Compare commits

...

29 Commits

Author SHA1 Message Date
Ettore Di Giacinto
bff45b9bd9 🆕 Tag 0.22.7 2022-01-09 14:45:13 +01:00
Ettore Di Giacinto
7e589b07b8 ⚙️ Resolve templates folder when syncing repositories
This fixes #284
2022-01-09 14:44:44 +01:00
Ettore Di Giacinto
9c61210b5b 🆕 Tag 0.22.6 2022-01-07 15:41:51 +01:00
Ettore Di Giacinto
519058f13c 🔧 Do not store file list of hidden packages 2022-01-07 00:02:22 +01:00
Ettore Di Giacinto
f0200018c7 🆕 Tag 0.22.5 2022-01-04 22:46:28 +01:00
Ettore Di Giacinto
6198eba3b8 ♻️ Drop travis file and chglog 2022-01-04 20:44:31 +01:00
Ettore Di Giacinto
9bd6730aeb 🤖 Adapt makefile/scripts to ginkgo changes 2022-01-04 18:47:21 +01:00
Ettore Di Giacinto
2bd623a61c 🔧 Drop containerd workaround
Partly reverts
37cc186c0b,
but re-enable test.
2022-01-04 17:03:21 +01:00
Ettore Di Giacinto
80bc5429bc 🆕 Tag 0.22.4 2021-12-28 22:08:04 +01:00
Ettore Di Giacinto
9274f87a80 🔧 ci: disable flaky test 2021-12-28 21:06:31 +01:00
Ettore Di Giacinto
1d651a5878 🔧 ci: disable -race on scripts/ginkgo.coverage.sh 2021-12-28 20:45:24 +01:00
Ettore Di Giacinto
f7357a60a6 🔧 ci: disable -race on tests
Seems race conditions are triggered from the go-containerregistry
underlying library.
2021-12-28 20:35:19 +01:00
Ettore Di Giacinto
57eedf8e7e 🆕 Tag 0.22.3 2021-12-28 19:02:20 +01:00
Ettore Di Giacinto
96aaf5235b 🔧 Update modules 2021-12-28 18:56:13 +01:00
Ettore Di Giacinto
196cdc5cfc 🔧 Extract common func into api function, also set sane defaults 2021-12-28 18:55:59 +01:00
Ettore Di Giacinto
719ef16161 🆕 Tag 0.22.2 2021-12-28 16:01:35 +01:00
Ettore Di Giacinto
1a9073a97a 🎨 Display installed packages in luet search
Fixes #236
2021-12-28 15:04:00 +01:00
Ettore Di Giacinto
7e825400e2 🔧 Use crane.Insecure while checking image availability
As those checks are not consuming any digest, we just use them to assess
if we need to build or not certain packages. The backend will refuse the
image if not configured appropriately
2021-12-28 14:54:11 +01:00
Ettore Di Giacinto
39e62f3321 🆕 Tag 0.22.1 2021-12-28 14:36:44 +01:00
Ettore Di Giacinto
9dcaeb0870 🔧 Defer write repository synctime 2021-12-28 12:06:09 +01:00
Ettore Di Giacinto
c4affb0f0e 🔧 Fixup live-output CLI parameter 2021-12-27 23:11:16 +01:00
Ludea
4c1b9b92af Unpack local image (#277)
* [WIP] Unpack local docker images

* unpack local image

* PR feedback + missing new function call

Co-authored-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
2021-12-26 20:06:15 +01:00
Ettore Di Giacinto
7f7e1418c1 Tag 0.22.0 2021-12-25 11:37:13 +01:00
Ettore Di Giacinto
e8c5e237b2 🎨 Display missing files in oscheck with --debug 2021-12-25 10:40:07 +01:00
Ettore Di Giacinto
a363b53043 🔧 Speedup package upgrades
Now we can just remove the necessary files and let the installation
handle the rest
2021-12-25 10:40:07 +01:00
Ettore Di Giacinto
c98f427156 🎨 Introduce contextualized logging
This commit is multi-fold as it also refactors internally context and logger
as interfaces so it is easier to plug luet as a library externally.

Introduces a garbage collector (related to #227) but doesn't handle yet
parallelism.

Closes #265
2021-12-21 21:54:14 +01:00
Ettore Di Giacinto
fd90e0d627 🆕 Tag 0.21.2 2021-12-18 17:30:30 +01:00
Ettore Di Giacinto
20d01e43c7 🎨 Update repos automatically only if out-of-sync
Fixes #274
Fixes #212
2021-12-18 16:32:03 +01:00
Ettore Di Giacinto
ed63236516 🔧 take into account of multiple installs 2021-12-18 15:32:35 +01:00
664 changed files with 23995 additions and 14564 deletions

View File

@@ -1,49 +0,0 @@
{{ if .Versions -}}
{{ if .Unreleased.CommitGroups -}}
{{ range .Unreleased.CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{ else }}
{{ range .Unreleased.Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{ end -}}
{{ range .Versions }}
<a name="{{ .Tag.Name }}"></a>
{{ if .CommitGroups -}}
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{ else }}
{{ range .Commits -}}
- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} (https://github.com/mudler/luet/commit/{{.Hash.Short}})
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}
{{- if .Versions }}
[Unreleased]: {{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD
{{ range .Versions -}}
{{ if .Tag.Previous -}}
[{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
{{ end -}}
{{ end -}}
{{ end -}}

View File

@@ -1,27 +0,0 @@
style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/mudler/luet
options:
commits:
# filters:
# Type:
# - feat
# - fix
# - perf
# - refactor
commit_groups:
title_maps:
feat: Features
fix: Bug Fixes
perf: Performance Improvements
refactor: Code Refactoring
ci: Continous Integration
header:
pattern: "(.*)"
pattern_maps:
- Subject
notes:
keywords:
- BREAKING CHANGE

View File

@@ -74,4 +74,8 @@ jobs:
- name: Build
run: sudo -E env "PATH=$PATH" make multiarch-build-small
- name: Tests
run: sudo -E env "PATH=$PATH" make test-coverage
run: sudo -E env "PATH=$PATH" make coverage
- name: Codecov
uses: codecov/codecov-action@v2.1.0
with:
file: coverage.txt

View File

@@ -84,4 +84,9 @@ jobs:
env "TEST_DOCKER_IMAGE=${{ secrets.DOCKER_TESTING_IMAGE }}" \
env "UNIT_TEST_DOCKER_IMAGE=${{ secrets.DOCKER_TESTING_IMAGE }}" \
env "UNIT_TEST_DOCKER_IMAGE_REPOSITORY=${{ secrets.DOCKER_TESTING_UNIT_TEST_IMAGE }}" \
make test-coverage
make coverage
- name: Codecov
uses: codecov/codecov-action@v2.1.0
with:
file: coverage.txt

View File

@@ -87,7 +87,11 @@ jobs:
env "TEST_DOCKER_IMAGE=${{ secrets.DOCKER_TESTING_IMAGE }}" \
env "UNIT_TEST_DOCKER_IMAGE=${{ secrets.DOCKER_TESTING_IMAGE }}" \
env "UNIT_TEST_DOCKER_IMAGE_REPOSITORY=${{ secrets.DOCKER_TESTING_UNIT_TEST_IMAGE }}" \
make test-coverage
make coverage
- name: Codecov
uses: codecov/codecov-action@v2.1.0
with:
file: coverage.txt
release:
name: Release
@@ -108,4 +112,4 @@ jobs:
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,35 +0,0 @@
dist: bionic
language: go
go:
- "1.14"
env:
global:
- "GO15VENDOREXPERIMENT=1"
jobs:
- "DOCKER_BUILDKIT=0"
- "DOCKER_BUILDKIT=1"
before_install:
- sudo rm -rf /var/lib/apt/lists/*
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge"
- sudo apt-get update
- echo '{"experimental":true}' | sudo tee /etc/docker/daemon.json
- export DOCKER_CLI_EXPERIMENTAL=enabled
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- mkdir -vp ~/.docker/cli-plugins/
- curl --silent -L "https://github.com/docker/buildx/releases/download/v0.3.0/buildx-v0.3.0.linux-amd64" > ~/.docker/cli-plugins/docker-buildx
- chmod a+x ~/.docker/cli-plugins/docker-buildx
- docker buildx version
- sudo -E env "PATH=$PATH" apt-get install -y libcap2-bin
- sudo -E env "PATH=$PATH" make deps
script:
- sudo -E env "PATH=$PATH" make multiarch-build test-integration test-coverage
#after_success:
# - |
# if [ -n "$TRAVIS_TAG" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
# sudo -E env "PATH=$PATH" git config --global user.name "Deployer" && git config --global user.email foo@bar.com
# sudo -E env "PATH=$PATH" go get github.com/tcnksm/ghr
# sudo -E env "PATH=$PATH" ghr -u mudler -r luet --replace $TRAVIS_TAG release/
# fi

View File

@@ -17,9 +17,10 @@ fmt:
.PHONY: test
test:
GO111MODULE=off go get github.com/onsi/ginkgo/ginkgo
GO111MODULE=off go get github.com/onsi/ginkgo/v2
go install github.com/onsi/ginkgo/v2/ginkgo
GO111MODULE=off go get github.com/onsi/gomega/...
ginkgo -race -r -flakeAttempts 3 ./...
ginkgo -r --flake-attempts=3 ./...
.PHONY: test-integration
test-integration:
@@ -27,11 +28,7 @@ test-integration:
.PHONY: coverage
coverage:
go test ./... -race -coverprofile=coverage.txt -covermode=atomic
.PHONY: test-coverage
test-coverage:
scripts/ginkgo.coverage.sh --codecov
ginkgo --flake-attempts=3 --fail-fast -cover -covermode=atomic -coverprofile=coverage.txt -r .
.PHONY: help
help:

View File

@@ -31,7 +31,6 @@ import (
"github.com/mudler/luet/pkg/compiler/types/options"
fileHelpers "github.com/mudler/luet/pkg/helpers/file"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/solver"
tree "github.com/mudler/luet/pkg/tree"
"github.com/spf13/cobra"
@@ -39,6 +38,10 @@ import (
)
var buildCmd = &cobra.Command{
// Skip processing output
Annotations: map[string]string{
util.CommandProcessOutput: "",
},
Use: "build <package name> <package name> <package name> ...",
Short: "build a package or a tree",
Long: `Builds one or more packages from a tree (current directory is implied):
@@ -83,9 +86,6 @@ Build packages specifying multiple definition trees:
viper.BindPFlag("wait", cmd.Flags().Lookup("wait"))
viper.BindPFlag("keep-images", cmd.Flags().Lookup("keep-images"))
util.BindSolverFlags(cmd)
viper.BindPFlag("general.show_build_output", cmd.Flags().Lookup("live-output"))
viper.BindPFlag("backend-args", cmd.Flags().Lookup("backend-args"))
},
@@ -93,7 +93,7 @@ Build packages specifying multiple definition trees:
treePaths := viper.GetStringSlice("tree")
dst := viper.GetString("destination")
concurrency := util.DefaultContext.Config.GetGeneral().Concurrency
concurrency := util.DefaultContext.Config.General.Concurrency
backendType := viper.GetString("backend")
privileged := viper.GetBool("privileged")
revdeps := viper.GetBool("revdeps")
@@ -116,11 +116,7 @@ Build packages specifying multiple definition trees:
var results Results
backendArgs := viper.GetStringSlice("backend-args")
out, _ := cmd.Flags().GetString("output")
if out != "terminal" {
util.DefaultContext.Config.GetLogging().SetLogLevel("error")
}
pretend, _ := cmd.Flags().GetBool("pretend")
fromRepo, _ := cmd.Flags().GetBool("from-repositories")
@@ -135,16 +131,21 @@ Build packages specifying multiple definition trees:
generalRecipe := tree.NewCompilerRecipe(db)
if fromRepo {
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 {
util.DefaultContext.Info("Loading tree", src)
helpers.CheckErr(generalRecipe.Load(src))
}
templateFolders := []string{}
if fromRepo {
bt, err := installer.LoadBuildTree(generalRecipe, db, util.DefaultContext)
if err != nil {
util.DefaultContext.Warning("errors while loading trees from repositories", err.Error())
}
templateFolders = util.TemplateFolders(util.DefaultContext, bt, treePaths)
} else {
templateFolders = util.TemplateFolders(util.DefaultContext, installer.BuildTreeResult{}, treePaths)
}
util.DefaultContext.Info("Building in", dst)
@@ -153,15 +154,11 @@ Build packages specifying multiple definition trees:
util.DefaultContext.Debug("Creating destination folder", dst)
}
opts := util.SetSolverConfig(util.DefaultContext)
opts := util.DefaultContext.GetConfig().Solver
pullRepo, _ := cmd.Flags().GetStringArray("pull-repository")
util.DefaultContext.Config.GetGeneral().ShowBuildOutput = viper.GetBool("general.show_build_output")
util.DefaultContext.Debug("Solver", opts.CompactString())
opts.Options = solver.Options{Type: solver.SingleCoreSimple, Concurrency: concurrency}
compileropts := []options.Option{options.NoDeps(nodeps),
options.WithBackendType(backendType),
options.PushImages(push),
@@ -169,8 +166,8 @@ Build packages specifying multiple definition trees:
options.WithPullRepositories(pullRepo),
options.WithPushRepository(imageRepository),
options.Rebuild(rebuild),
options.WithTemplateFolder(util.TemplateFolders(util.DefaultContext, fromRepo, treePaths)),
options.WithSolverOptions(*opts),
options.WithTemplateFolder(templateFolders),
options.WithSolverOptions(opts),
options.Wait(wait),
options.OnlyTarget(onlyTarget),
options.PullFirst(pull),
@@ -341,7 +338,6 @@ 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", 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")

View File

@@ -31,16 +31,13 @@ var cleanupCmd = &cobra.Command{
Use: "cleanup",
Short: "Clean packages cache.",
Long: `remove downloaded packages tarballs and clean cache directory`,
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
},
Run: func(cmd *cobra.Command, args []string) {
var cleaned int = 0
util.SetSystemConfig(util.DefaultContext)
// Check if cache dir exists
if fileHelper.Exists(util.DefaultContext.Config.GetSystem().GetSystemPkgsCacheDirPath()) {
if fileHelper.Exists(util.DefaultContext.Config.System.PkgsCachePath) {
files, err := ioutil.ReadDir(util.DefaultContext.Config.GetSystem().GetSystemPkgsCacheDirPath())
files, err := ioutil.ReadDir(util.DefaultContext.Config.System.PkgsCachePath)
if err != nil {
util.DefaultContext.Fatal("Error on read cachedir ", err.Error())
}
@@ -50,7 +47,7 @@ var cleanupCmd = &cobra.Command{
util.DefaultContext.Debug("Removing ", file.Name())
err := os.RemoveAll(
filepath.Join(util.DefaultContext.Config.GetSystem().GetSystemPkgsCacheDirPath(), file.Name()))
filepath.Join(util.DefaultContext.Config.System.PkgsCachePath, file.Name()))
if err != nil {
util.DefaultContext.Fatal("Error on removing", file.Name())
}
@@ -58,14 +55,11 @@ var cleanupCmd = &cobra.Command{
}
}
util.DefaultContext.Info(fmt.Sprintf("Cleaned: %d files from %s", cleaned, util.DefaultContext.Config.GetSystem().GetSystemPkgsCacheDirPath()))
util.DefaultContext.Info(fmt.Sprintf("Cleaned: %d files from %s", cleaned, util.DefaultContext.Config.System.PkgsCachePath))
},
}
func init() {
cleanupCmd.Flags().String("system-dbpath", "", "System db path")
cleanupCmd.Flags().String("system-target", "", "System rootpath")
cleanupCmd.Flags().String("system-engine", "", "System DB engine")
RootCmd.AddCommand(cleanupCmd)
}

View File

@@ -27,7 +27,7 @@ import (
)
func NewDatabaseCreateCommand() *cobra.Command {
var ans = &cobra.Command{
return &cobra.Command{
Use: "create <artifact_metadata1.yaml> <artifact_metadata1.yaml>",
Short: "Insert a package in the system DB",
Long: `Inserts a package in the system database:
@@ -42,12 +42,8 @@ The yaml must contain the package definition, and the file list at least.
For reference, inspect a "metadata.yaml" file generated while running "luet build"`,
Args: cobra.OnlyValidArgs,
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
},
Run: func(cmd *cobra.Command, args []string) {
util.SetSystemConfig(util.DefaultContext)
systemDB := util.DefaultContext.Config.GetSystemDB()
for _, a := range args {
@@ -81,9 +77,4 @@ For reference, inspect a "metadata.yaml" file generated while running "luet buil
},
}
ans.Flags().String("system-dbpath", "", "System db path")
ans.Flags().String("system-target", "", "System rootpath")
ans.Flags().String("system-engine", "", "System DB engine")
return ans
}

View File

@@ -36,12 +36,9 @@ func NewDatabaseGetCommand() *cobra.Command {
To return also files:
$ luet database get --files system/foo`,
Args: cobra.OnlyValidArgs,
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
},
Run: func(cmd *cobra.Command, args []string) {
showFiles, _ := cmd.Flags().GetBool("files")
util.SetSystemConfig(util.DefaultContext)
systemDB := util.DefaultContext.Config.GetSystemDB()
@@ -77,9 +74,6 @@ To return also files:
},
}
c.Flags().Bool("files", false, "Show package files.")
c.Flags().String("system-dbpath", "", "System db path")
c.Flags().String("system-target", "", "System rootpath")
c.Flags().String("system-engine", "", "System DB engine")
return c
}

View File

@@ -23,7 +23,7 @@ import (
)
func NewDatabaseRemoveCommand() *cobra.Command {
var ans = &cobra.Command{
return &cobra.Command{
Use: "remove [package1] [package2] ...",
Short: "Remove a package from the system DB (forcefully - you normally don't want to do that)",
Long: `Removes a package in the system database without actually uninstalling it:
@@ -33,11 +33,8 @@ func NewDatabaseRemoveCommand() *cobra.Command {
This commands takes multiple packages as arguments and prunes their entries from the system database.
`,
Args: cobra.OnlyValidArgs,
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
},
Run: func(cmd *cobra.Command, args []string) {
util.SetSystemConfig(util.DefaultContext)
systemDB := util.DefaultContext.Config.GetSystemDB()
@@ -58,9 +55,5 @@ This commands takes multiple packages as arguments and prunes their entries from
},
}
ans.Flags().String("system-dbpath", "", "System db path")
ans.Flags().String("system-target", "", "System rootpath")
ans.Flags().String("system-engine", "", "System DB engine")
return ans
}

View File

@@ -18,7 +18,7 @@ package cmd_helpers_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -18,7 +18,7 @@ package cmd_helpers_test
import (
. "github.com/mudler/luet/cmd/helpers"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -15,9 +15,7 @@
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"
@@ -48,8 +46,6 @@ To force install a package:
`,
Aliases: []string{"i"},
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
util.BindSolverFlags(cmd)
viper.BindPFlag("onlydeps", cmd.Flags().Lookup("onlydeps"))
viper.BindPFlag("nodeps", cmd.Flags().Lookup("nodeps"))
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
@@ -71,28 +67,13 @@ To force install a package:
onlydeps := viper.GetBool("onlydeps")
yes := viper.GetBool("yes")
downloadOnly, _ := cmd.Flags().GetBool("download-only")
finalizerEnvs, _ := cmd.Flags().GetStringArray("finalizer-env")
relax, _ := cmd.Flags().GetBool("relax")
util.SetSystemConfig(util.DefaultContext)
util.SetSolverConfig(util.DefaultContext)
util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString())
// Load config protect configs
util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext)
// Load finalizer runtime environments
err := util.SetCliFinalizerEnvs(util.DefaultContext, finalizerEnvs)
if err != nil {
util.DefaultContext.Fatal(err.Error())
}
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.Solver.CompactString())
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
NoDeps: nodeps,
Force: force,
OnlyDeps: onlydeps,
@@ -104,8 +85,11 @@ To force install a package:
Context: util.DefaultContext,
})
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
err = inst.Install(toInstall, system)
system := &installer.System{
Database: util.DefaultContext.Config.GetSystemDB(),
Target: util.DefaultContext.Config.System.Rootfs,
}
err := inst.Install(toInstall, system)
if err != nil {
util.DefaultContext.Fatal("Error: " + err.Error())
}
@@ -113,14 +97,7 @@ To force install a package:
}
func init() {
installCmd.Flags().String("system-dbpath", "", "System db path")
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: "+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")
installCmd.Flags().Bool("nodeps", false, "Don't consider package dependencies (harmful!)")
installCmd.Flags().Bool("relax", false, "Relax installation constraints")

View File

@@ -19,10 +19,8 @@ import (
"os"
"strings"
"github.com/mudler/luet/pkg/api/core/types"
installer "github.com/mudler/luet/pkg/installer"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/solver"
"github.com/mudler/luet/cmd/util"
@@ -43,8 +41,6 @@ To reinstall packages in the list:
`,
Aliases: []string{"i"},
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
util.BindSolverFlags(cmd)
viper.BindPFlag("onlydeps", cmd.Flags().Lookup("onlydeps"))
viper.BindPFlag("nodeps", cmd.Flags().Lookup("nodeps"))
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
@@ -57,10 +53,12 @@ To reinstall packages in the list:
yes := viper.GetBool("yes")
downloadOnly, _ := cmd.Flags().GetBool("download-only")
util.SetSystemConfig(util.DefaultContext)
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
packs := system.OSCheck()
system := &installer.System{
Database: util.DefaultContext.Config.GetSystemDB(),
Target: util.DefaultContext.Config.System.Rootfs,
}
packs := system.OSCheck(util.DefaultContext)
if !util.DefaultContext.Config.General.Quiet {
if len(packs) == 0 {
util.DefaultContext.Success("All good!")
@@ -90,18 +88,11 @@ To reinstall packages in the list:
toInstall = append(toInstall, new)
}
util.SetSolverConfig(util.DefaultContext)
util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString())
// Load config protect configs
util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext)
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.Solver.CompactString())
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
NoDeps: true,
Force: force,
OnlyDeps: onlydeps,
@@ -121,18 +112,11 @@ To reinstall packages in the list:
}
func init() {
osCheckCmd.Flags().String("system-dbpath", "", "System db path")
osCheckCmd.Flags().String("system-target", "", "System rootpath")
osCheckCmd.Flags().String("system-engine", "", "System DB engine")
osCheckCmd.Flags().Bool("reinstall", false, "reinstall")
osCheckCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )")
osCheckCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")
osCheckCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
osCheckCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
osCheckCmd.Flags().Bool("onlydeps", false, "Consider **only** package dependencies")
osCheckCmd.Flags().Bool("force", false, "Skip errors and keep going (potentially harmful)")
osCheckCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
osCheckCmd.Flags().BoolP("yes", "y", false, "Don't ask questions")
osCheckCmd.Flags().Bool("download-only", false, "Download only")

View File

@@ -52,7 +52,7 @@ Afterwards, you can use the content generated and associate it with a tree and a
dst := viper.GetString("destination")
compressionType := viper.GetString("compression")
concurrency := util.DefaultContext.Config.GetGeneral().Concurrency
concurrency := util.DefaultContext.Config.General.Concurrency
if len(args) != 1 {
util.DefaultContext.Fatal("You must specify a package name")

View File

@@ -26,7 +26,6 @@ var reclaimCmd = &cobra.Command{
Use: "reclaim",
Short: "Reclaim packages to Luet database from available repositories",
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
},
Long: `Reclaim tries to find association between packages in the online repositories and the system one.
@@ -36,21 +35,23 @@ 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.DefaultContext)
force := viper.GetBool("force")
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString())
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.Solver.CompactString())
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
Concurrency: util.DefaultContext.Config.General.Concurrency,
Force: force,
PreserveSystemEssentialData: true,
PackageRepositories: util.DefaultContext.Config.SystemRepositories,
Context: util.DefaultContext,
})
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
system := &installer.System{
Database: util.DefaultContext.Config.GetSystemDB(),
Target: util.DefaultContext.Config.System.Rootfs,
}
err := inst.Reclaim(system)
if err != nil {
util.DefaultContext.Fatal("Error: " + err.Error())
@@ -60,10 +61,6 @@ It scans the target file system, and if finds a match with a package available i
func init() {
reclaimCmd.Flags().String("system-dbpath", "", "System db path")
reclaimCmd.Flags().String("system-target", "", "System rootpath")
reclaimCmd.Flags().String("system-engine", "", "System DB engine")
reclaimCmd.Flags().Bool("force", false, "Skip errors and keep going (potentially harmful)")
RootCmd.AddCommand(reclaimCmd)

View File

@@ -15,9 +15,7 @@
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"
@@ -35,8 +33,6 @@ var reinstallCmd = &cobra.Command{
$ luet reinstall -y system/busybox shells/bash system/coreutils ...
`,
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
util.BindSolverFlags(cmd)
viper.BindPFlag("onlydeps", cmd.Flags().Lookup("onlydeps"))
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
viper.BindPFlag("for", cmd.Flags().Lookup("for"))
@@ -54,20 +50,11 @@ var reinstallCmd = &cobra.Command{
downloadOnly, _ := cmd.Flags().GetBool("download-only")
installed, _ := cmd.Flags().GetBool("installed")
util.SetSystemConfig(util.DefaultContext)
util.SetSolverConfig(util.DefaultContext)
util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString())
// Load config protect configs
util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext)
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.Solver.CompactString())
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
NoDeps: true,
Force: force,
OnlyDeps: onlydeps,
@@ -78,7 +65,7 @@ var reinstallCmd = &cobra.Command{
PackageRepositories: util.DefaultContext.Config.SystemRepositories,
})
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.System.Rootfs}
if installed {
for _, p := range system.Database.World() {
@@ -106,18 +93,8 @@ var reinstallCmd = &cobra.Command{
}
func init() {
reinstallCmd.Flags().String("system-dbpath", "", "System db path")
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: "+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")
reinstallCmd.Flags().Bool("onlydeps", false, "Consider **only** package dependencies")
reinstallCmd.Flags().Bool("force", false, "Skip errors and keep going (potentially harmful)")
reinstallCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
reinstallCmd.Flags().Bool("installed", false, "Reinstall installed packages")
reinstallCmd.Flags().BoolP("yes", "y", false, "Don't ask questions")
reinstallCmd.Flags().Bool("download-only", false, "Download only")

View File

@@ -15,7 +15,6 @@
package cmd
import (
"github.com/mudler/luet/pkg/api/core/types"
installer "github.com/mudler/luet/pkg/installer"
"github.com/mudler/luet/pkg/solver"
@@ -37,8 +36,6 @@ var replaceCmd = &cobra.Command{
$ luet replace -y system/busybox ... --for shells/bash --for system/coreutils ...
`,
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
util.BindSolverFlags(cmd)
viper.BindPFlag("onlydeps", cmd.Flags().Lookup("onlydeps"))
viper.BindPFlag("nodeps", cmd.Flags().Lookup("nodeps"))
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
@@ -57,8 +54,6 @@ var replaceCmd = &cobra.Command{
yes := viper.GetBool("yes")
downloadOnly, _ := cmd.Flags().GetBool("download-only")
util.SetSystemConfig(util.DefaultContext)
util.SetSolverConfig(util.DefaultContext)
for _, a := range args {
pack, err := helpers.ParsePackageStr(a)
if err != nil {
@@ -75,16 +70,13 @@ var replaceCmd = &cobra.Command{
toAdd = append(toAdd, pack)
}
util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple
util.DefaultContext.Config.Solver.Implementation = solver.SingleCoreSimple
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString())
// Load config protect configs
util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext)
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.Solver.CompactString())
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
NoDeps: nodeps,
Force: force,
OnlyDeps: onlydeps,
@@ -95,7 +87,7 @@ var replaceCmd = &cobra.Command{
Context: util.DefaultContext,
})
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.System.Rootfs}
err := inst.Swap(toUninstall, toAdd, system)
if err != nil {
util.DefaultContext.Fatal("Error: " + err.Error())
@@ -105,18 +97,9 @@ var replaceCmd = &cobra.Command{
func init() {
replaceCmd.Flags().String("system-dbpath", "", "System db path")
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: "+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")
replaceCmd.Flags().Bool("nodeps", false, "Don't consider package dependencies (harmful!)")
replaceCmd.Flags().Bool("onlydeps", false, "Consider **only** package dependencies")
replaceCmd.Flags().Bool("force", false, "Skip errors and keep going (potentially harmful)")
replaceCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
replaceCmd.Flags().BoolP("yes", "y", false, "Don't ask questions")
replaceCmd.Flags().StringSlice("for", []string{}, "Packages that has to be installed in place of others")
replaceCmd.Flags().Bool("download-only", false, "Download only")

View File

@@ -68,7 +68,7 @@ func NewRepoListCommand() *cobra.Command {
repoText = pterm.LightYellow(repo.Urls[0])
}
repobasedir := util.DefaultContext.Config.GetSystem().GetRepoDatabaseDirPath(repo.Name)
repobasedir := util.DefaultContext.Config.System.GetRepoDatabaseDirPath(repo.Name)
if repo.Cached {
r := installer.NewSystemRepository(repo)

View File

@@ -1,5 +1,6 @@
// Copyright © 2019 Ettore Di Giacinto <mudler@gentoo.org>
// Daniele Rondina <geaaru@sabayonlinux.org>
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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,7 +25,7 @@ import (
)
func NewRepoUpdateCommand() *cobra.Command {
var ans = &cobra.Command{
var repoUpdate = &cobra.Command{
Use: "update [repo1] [repo2] [OPTIONS]",
Short: "Update a specific cached repository or all cached repositories.",
Example: `
@@ -72,8 +73,8 @@ $> luet repo update repo1 repo2
},
}
ans.Flags().BoolP("ignore-errors", "i", false, "Ignore errors on sync repositories.")
ans.Flags().BoolP("force", "f", false, "Force resync.")
repoUpdate.Flags().BoolP("ignore-errors", "i", false, "Ignore errors on sync repositories.")
repoUpdate.Flags().BoolP("force", "f", true, "Force resync.")
return ans
return repoUpdate
}

View File

@@ -30,7 +30,7 @@ var cfgFile string
var Verbose bool
const (
LuetCLIVersion = "0.21.1"
LuetCLIVersion = "0.22.7"
LuetEnvPrefix = "LUET"
)
@@ -81,19 +81,15 @@ To build a package, from a tree definition:
`,
Version: version(),
PersistentPreRun: func(cmd *cobra.Command, args []string) {
err := util.InitContext(util.DefaultContext)
ctx, err := util.InitContext(cmd)
if err != nil {
util.DefaultContext.Error("failed to load configuration:", err.Error())
fmt.Println("failed to load configuration:", err.Error())
os.Exit(1)
}
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 = util.DefaultContext.Config.GetSystem().InitTmpDir()
if err != nil {
util.DefaultContext.Fatal("failed on init tmp basedir:", err.Error())
}
util.DefaultContext = ctx
util.DisplayVersionBanner(util.DefaultContext, util.IntroScreen, version, license)
viper.BindPFlag("plugin", cmd.Flags().Lookup("plugin"))
@@ -109,7 +105,7 @@ To build a package, from a tree definition:
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
// Cleanup all tmp directories used by luet
err := util.DefaultContext.Config.GetSystem().CleanupTmpDir()
err := util.DefaultContext.Clean()
if err != nil {
util.DefaultContext.Warning("failed on cleanup tmpdir:", err.Error())
}
@@ -129,5 +125,5 @@ func Execute() {
}
func init() {
util.InitViper(util.DefaultContext, RootCmd)
util.InitViper(RootCmd)
}

View File

@@ -20,7 +20,6 @@ import (
"github.com/ghodss/yaml"
"github.com/mudler/luet/cmd/util"
"github.com/mudler/luet/pkg/api/core/types"
installer "github.com/mudler/luet/pkg/installer"
pkg "github.com/mudler/luet/pkg/package"
"github.com/pterm/pterm"
@@ -36,6 +35,7 @@ type PackageResult struct {
Target string `json:"target"`
Hidden bool `json:"hidden"`
Files []string `json:"files"`
Installed bool `json:"installed"`
}
type Results struct {
@@ -46,13 +46,13 @@ func (r PackageResult) String() string {
return fmt.Sprintf("%s/%s-%s required for %s", r.Category, r.Name, r.Version, r.Target)
}
var rows []string = []string{"Package", "Category", "Name", "Version", "Repository", "License"}
var rows []string = []string{"Package", "Category", "Name", "Version", "Repository", "License", "Installed"}
func packageToRow(repo string, p pkg.Package) []string {
return []string{p.HumanReadableString(), p.GetCategory(), p.GetName(), p.GetVersion(), repo, p.GetLicense()}
func packageToRow(repo string, p pkg.Package, installed bool) []string {
return []string{p.HumanReadableString(), p.GetCategory(), p.GetName(), p.GetVersion(), repo, p.GetLicense(), fmt.Sprintf("%t", installed)}
}
func packageToList(l *util.ListWriter, repo string, p pkg.Package) {
func packageToList(l *util.ListWriter, repo string, p pkg.Package, installed bool) {
l.AppendItem(pterm.BulletListItem{
Level: 0, Text: p.HumanReadableString(),
TextStyle: pterm.NewStyle(pterm.FgCyan), Bullet: ">", BulletStyle: pterm.NewStyle(pterm.FgYellow),
@@ -81,12 +81,32 @@ func packageToList(l *util.ListWriter, repo string, p pkg.Package) {
Level: 1, Text: fmt.Sprintf("Uri: %s ", strings.Join(p.GetURI(), " ")),
Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray),
})
l.AppendItem(pterm.BulletListItem{
Level: 1, Text: fmt.Sprintf("Installed: %t ", installed),
Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray),
})
}
var s *installer.System
func sys() *installer.System {
if s != nil {
return s
}
s = &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.System.Rootfs}
return s
}
func installed(p pkg.Package) bool {
s := sys()
_, err := s.Database.FindPackage(p)
return err == nil
}
func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label, labelMatch, revdeps, hidden bool) Results {
var results Results
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
system := sys()
var err error
iMatches := pkg.Packages{}
@@ -105,9 +125,8 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
for _, pack := range iMatches {
if !revdeps {
if !pack.IsHidden() || pack.IsHidden() && hidden {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
t.AppendRow(packageToRow("system", pack, true))
packageToList(l, "system", pack, true)
f, _ := system.Database.GetPackageFiles(pack)
results.Packages = append(results.Packages,
PackageResult{
@@ -117,6 +136,7 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
Repository: "system",
Hidden: pack.IsHidden(),
Files: f,
Installed: true,
})
}
} else {
@@ -124,8 +144,9 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
packs, _ := system.Database.GetRevdeps(pack)
for _, revdep := range packs {
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
i := installed(pack)
t.AppendRow(packageToRow("system", pack, i))
packageToList(l, "system", pack, i)
f, _ := system.Database.GetPackageFiles(revdep)
results.Packages = append(results.Packages,
PackageResult{
@@ -135,6 +156,7 @@ func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label,
Repository: "system",
Hidden: revdep.IsHidden(),
Files: f,
Installed: i,
})
}
}
@@ -148,8 +170,8 @@ func searchOnline(term string, l *util.ListWriter, t *util.TableWriter, label, l
inst := installer.NewLuetInstaller(
installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
PackageRepositories: util.DefaultContext.Config.SystemRepositories,
Context: util.DefaultContext,
},
@@ -173,14 +195,16 @@ func searchOnline(term string, l *util.ListWriter, t *util.TableWriter, label, l
for _, m := range matches {
if !revdeps {
if !m.Package.IsHidden() || m.Package.IsHidden() && hidden {
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package))
packageToList(l, m.Repo.GetName(), m.Package)
i := installed(m.Package)
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package, i))
packageToList(l, m.Repo.GetName(), m.Package, i)
r := &PackageResult{
Name: m.Package.GetName(),
Version: m.Package.GetVersion(),
Category: m.Package.GetCategory(),
Repository: m.Repo.GetName(),
Hidden: m.Package.IsHidden(),
Installed: i,
}
if m.Artifact != nil {
r.Files = m.Artifact.Files
@@ -191,10 +215,12 @@ func searchOnline(term string, l *util.ListWriter, t *util.TableWriter, label, l
packs, _ := m.Repo.GetTree().GetDatabase().GetRevdeps(m.Package)
for _, revdep := range packs {
if !revdep.IsHidden() || revdep.IsHidden() && hidden {
t.AppendRow(packageToRow(m.Repo.GetName(), revdep))
packageToList(l, m.Repo.GetName(), revdep)
i := installed(revdep)
t.AppendRow(packageToRow(m.Repo.GetName(), revdep, i))
packageToList(l, m.Repo.GetName(), revdep, i)
r := &PackageResult{
Name: revdep.GetName(),
Installed: i,
Version: revdep.GetVersion(),
Category: revdep.GetCategory(),
Repository: m.Repo.GetName(),
@@ -216,8 +242,9 @@ func searchLocalFiles(term string, l *util.ListWriter, t *util.TableWriter) Resu
matches, _ := util.DefaultContext.Config.GetSystemDB().FindPackageByFile(term)
for _, pack := range matches {
t.AppendRow(packageToRow("system", pack))
packageToList(l, "system", pack)
i := installed(pack)
t.AppendRow(packageToRow("system", pack, i))
packageToList(l, "system", pack, i)
f, _ := util.DefaultContext.Config.GetSystemDB().GetPackageFiles(pack)
results.Packages = append(results.Packages,
PackageResult{
@@ -227,6 +254,7 @@ func searchLocalFiles(term string, l *util.ListWriter, t *util.TableWriter) Resu
Repository: "system",
Hidden: pack.IsHidden(),
Files: f,
Installed: i,
})
}
@@ -238,8 +266,8 @@ func searchFiles(term string, l *util.ListWriter, t *util.TableWriter) Results {
inst := installer.NewLuetInstaller(
installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
PackageRepositories: util.DefaultContext.Config.SystemRepositories,
Context: util.DefaultContext,
},
@@ -256,8 +284,9 @@ func searchFiles(term string, l *util.ListWriter, t *util.TableWriter) Results {
matches = synced.SearchPackages(term, installer.FileSearch)
for _, m := range matches {
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package))
packageToList(l, m.Repo.GetName(), m.Package)
i := installed(m.Package)
t.AppendRow(packageToRow(m.Repo.GetName(), m.Package, i))
packageToList(l, m.Repo.GetName(), m.Package, i)
results.Packages = append(results.Packages,
PackageResult{
Name: m.Package.GetName(),
@@ -266,13 +295,18 @@ func searchFiles(term string, l *util.ListWriter, t *util.TableWriter) Results {
Repository: m.Repo.GetName(),
Hidden: m.Package.IsHidden(),
Files: m.Artifact.Files,
Installed: i,
})
}
return results
}
var searchCmd = &cobra.Command{
Use: "search <term>",
Use: "search <term>",
// Skip processing output
Annotations: map[string]string{
util.CommandProcessOutput: "",
},
Short: "Search packages",
Long: `Search for installed and available packages
@@ -309,8 +343,7 @@ Search can also return results in the terminal in different ways: as terminal ou
`,
Aliases: []string{"s"},
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
util.BindSolverFlags(cmd)
viper.BindPFlag("installed", cmd.Flags().Lookup("installed"))
},
Run: func(cmd *cobra.Command, args []string) {
@@ -329,18 +362,11 @@ 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.DefaultContext)
util.SetSolverConfig(util.DefaultContext)
out, _ := cmd.Flags().GetString("output")
if out != "terminal" {
util.DefaultContext.Config.GetLogging().SetLogLevel(types.FatalLevel)
}
l := &util.ListWriter{}
t := &util.TableWriter{}
t.AppendRow(rows)
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString())
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.Solver.CompactString())
switch {
case files && installed:
@@ -383,16 +409,9 @@ Search can also return results in the terminal in different ways: as terminal ou
}
func init() {
searchCmd.Flags().String("system-dbpath", "", "System db path")
searchCmd.Flags().String("system-target", "", "System rootpath")
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: "+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")
searchCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
searchCmd.Flags().Bool("by-label", false, "Search packages through label")
searchCmd.Flags().Bool("by-label-regex", false, "Search packages through label regex")
searchCmd.Flags().Bool("revdeps", false, "Search package reverse dependencies")

View File

@@ -26,6 +26,7 @@ import (
"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/installer"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/solver"
@@ -38,7 +39,11 @@ import (
func NewTreeImageCommand() *cobra.Command {
var ans = &cobra.Command{
Use: "images [OPTIONS]",
Use: "images [OPTIONS]",
// Skip processing output
Annotations: map[string]string{
util.CommandProcessOutput: "",
},
Short: "List of the images of a package",
PreRun: func(cmd *cobra.Command, args []string) {
t, _ := cmd.Flags().GetStringArray("tree")
@@ -60,12 +65,7 @@ func NewTreeImageCommand() *cobra.Command {
imageRepository := viper.GetString("image-repository")
pullRepo, _ := cmd.Flags().GetStringArray("pull-repository")
values := util.ValuesFlags()
out, _ := cmd.Flags().GetString("output")
if out != "terminal" {
util.DefaultContext.Config.GetLogging().SetLogLevel("error")
}
reciper := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false))
for _, t := range treePath {
@@ -76,7 +76,7 @@ func NewTreeImageCommand() *cobra.Command {
}
compilerBackend := backend.NewSimpleDockerBackend(util.DefaultContext)
opts := *util.DefaultContext.Config.GetSolverOptions()
opts := util.DefaultContext.Config.Solver
opts.Options = solver.Options{Type: solver.SingleCoreSimple, Concurrency: 1}
luetCompiler := compiler.NewLuetCompiler(
compilerBackend,
@@ -85,7 +85,7 @@ func NewTreeImageCommand() *cobra.Command {
options.WithContext(util.DefaultContext),
options.WithPushRepository(imageRepository),
options.WithPullRepositories(pullRepo),
options.WithTemplateFolder(util.TemplateFolders(util.DefaultContext, false, treePath)),
options.WithTemplateFolder(util.TemplateFolders(util.DefaultContext, installer.BuildTreeResult{}, treePath)),
options.WithSolverOptions(opts),
)

View File

@@ -67,6 +67,10 @@ func NewTreePkglistCommand() *cobra.Command {
var matches []string
var ans = &cobra.Command{
// Skip processing output
Annotations: map[string]string{
util.CommandProcessOutput: "",
},
Use: "pkglist [OPTIONS]",
Short: "List of the packages found in tree.",
Args: cobra.NoArgs,
@@ -95,9 +99,6 @@ func NewTreePkglistCommand() *cobra.Command {
deps, _ := cmd.Flags().GetBool("deps")
out, _ := cmd.Flags().GetString("output")
if out != "terminal" {
util.DefaultContext.Config.GetLogging().SetLogLevel("error")
}
var reciper tree.Builder
if buildtime {

View File

@@ -255,7 +255,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe
r.GetCategory(), r.GetName(), r.GetVersion(),
))
if util.DefaultContext.Config.GetGeneral().Debug {
if util.DefaultContext.Config.General.Debug {
for idx, pa := range solution {
fmt.Println(fmt.Sprintf("[%9s] %s/%s-%s: solution %d: %s",
checkType,
@@ -426,7 +426,7 @@ func NewTreeValidateCommand() *cobra.Command {
Run: func(cmd *cobra.Command, args []string) {
var reciper tree.Builder
concurrency := util.DefaultContext.Config.GetGeneral().Concurrency
concurrency := util.DefaultContext.Config.General.Concurrency
withSolver, _ := cmd.Flags().GetBool("with-solver")
onlyRuntime, _ := cmd.Flags().GetBool("only-runtime")

View File

@@ -17,7 +17,6 @@ package cmd
import (
helpers "github.com/mudler/luet/cmd/helpers"
"github.com/mudler/luet/cmd/util"
"github.com/mudler/luet/pkg/api/core/types"
installer "github.com/mudler/luet/pkg/installer"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/solver"
@@ -32,8 +31,7 @@ var uninstallCmd = &cobra.Command{
Long: `Uninstall packages`,
Aliases: []string{"rm", "un"},
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
util.BindSolverFlags(cmd)
viper.BindPFlag("nodeps", cmd.Flags().Lookup("nodeps"))
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
viper.BindPFlag("yes", cmd.Flags().Lookup("yes"))
@@ -57,21 +55,15 @@ var uninstallCmd = &cobra.Command{
yes := viper.GetBool("yes")
keepProtected, _ := cmd.Flags().GetBool("keep-protected-files")
util.SetSystemConfig(util.DefaultContext)
util.SetSolverConfig(util.DefaultContext)
util.DefaultContext.Config.ConfigProtectSkip = !keepProtected
util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple
util.DefaultContext.Config.Solver.Implementation = solver.SingleCoreSimple
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString())
// Load config protect configs
util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext)
util.DefaultContext.Debug("Solver", util.DefaultContext.Config.Solver.CompactString())
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
NoDeps: nodeps,
Force: force,
FullUninstall: full,
@@ -82,7 +74,7 @@ var uninstallCmd = &cobra.Command{
Context: util.DefaultContext,
})
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.System.Rootfs}
if err := inst.Uninstall(system, toRemove...); err != nil {
util.DefaultContext.Fatal("Error: " + err.Error())
@@ -92,14 +84,6 @@ var uninstallCmd = &cobra.Command{
func init() {
uninstallCmd.Flags().String("system-dbpath", "", "System db path")
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: "+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")
uninstallCmd.Flags().Bool("nodeps", false, "Don't consider package dependencies (harmful! overrides checkconflicts and full!)")
uninstallCmd.Flags().Bool("force", false, "Force uninstall")
uninstallCmd.Flags().Bool("full", false, "Attempts to remove as much packages as possible which aren't required (slow)")

View File

@@ -16,7 +16,6 @@ package cmd
import (
"github.com/mudler/luet/cmd/util"
"github.com/mudler/luet/pkg/api/core/types"
installer "github.com/mudler/luet/pkg/installer"
"github.com/mudler/luet/pkg/solver"
@@ -29,8 +28,7 @@ var upgradeCmd = &cobra.Command{
Short: "Upgrades the system",
Aliases: []string{"u"},
PreRun: func(cmd *cobra.Command, args []string) {
util.BindSystemFlags(cmd)
util.BindSolverFlags(cmd)
viper.BindPFlag("force", cmd.Flags().Lookup("force"))
viper.BindPFlag("yes", cmd.Flags().Lookup("yes"))
},
@@ -48,19 +46,13 @@ var upgradeCmd = &cobra.Command{
yes := viper.GetBool("yes")
downloadOnly, _ := cmd.Flags().GetBool("download-only")
util.SetSystemConfig(util.DefaultContext)
opts := util.SetSolverConfig(util.DefaultContext)
util.DefaultContext.Config.Solver.Implementation = solver.SingleCoreSimple
util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple
util.DefaultContext.Debug("Solver", opts.CompactString())
// Load config protect configs
util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext)
util.DefaultContext.Debug("Solver", util.DefaultContext.GetConfig().Solver)
inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{
Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency,
SolverOptions: *util.DefaultContext.Config.GetSolverOptions(),
Concurrency: util.DefaultContext.Config.General.Concurrency,
SolverOptions: util.DefaultContext.Config.Solver,
Force: force,
FullUninstall: full,
NoDeps: nodeps,
@@ -75,7 +67,7 @@ var upgradeCmd = &cobra.Command{
Context: util.DefaultContext,
})
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs}
system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.System.Rootfs}
if err := inst.Upgrade(system); err != nil {
util.DefaultContext.Fatal("Error: " + err.Error())
}
@@ -83,14 +75,6 @@ var upgradeCmd = &cobra.Command{
}
func init() {
upgradeCmd.Flags().String("system-dbpath", "", "System db path")
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: "+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")
upgradeCmd.Flags().Bool("force", false, "Force upgrade by ignoring errors")
upgradeCmd.Flags().Bool("nodeps", false, "Don't consider package dependencies (harmful! overrides checkconflicts and full!)")
upgradeCmd.Flags().Bool("full", false, "Attempts to remove as much packages as possible which aren't required (slow)")

View File

@@ -24,19 +24,19 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/go-units"
"github.com/mudler/luet/pkg/api/core/image"
luettypes "github.com/mudler/luet/pkg/api/core/types"
fileHelper "github.com/mudler/luet/pkg/helpers/file"
"github.com/pkg/errors"
"github.com/mudler/luet/cmd/util"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/helpers/docker"
"github.com/spf13/cobra"
)
func pack(ctx *luettypes.Context, p, dst, imageName, arch, OS string) error {
func pack(ctx *context.Context, p, dst, imageName, arch, OS string) error {
tempimage, err := ctx.Config.GetSystem().TempFile("tempimage")
tempimage, err := ctx.TempFile("tempimage")
if err != nil {
return errors.Wrap(err, "error met while creating tempdir for "+p)
}
@@ -89,7 +89,7 @@ func NewUnpackCommand() *cobra.Command {
Use: "unpack image path",
Short: "Unpack a docker image natively",
Long: `unpack doesn't need the docker daemon to run, and unpacks a docker image in the specified directory:
luet util unpack golang:alpine /alpine
`,
PreRun: func(cmd *cobra.Command, args []string) {
@@ -107,7 +107,7 @@ func NewUnpackCommand() *cobra.Command {
util.DefaultContext.Error("Invalid path %s", destination)
os.Exit(1)
}
local, _ := cmd.Flags().GetBool("local")
verify, _ := cmd.Flags().GetBool("verify")
user, _ := cmd.Flags().GetString("auth-username")
pass, _ := cmd.Flags().GetString("auth-password")
@@ -126,13 +126,22 @@ func NewUnpackCommand() *cobra.Command {
RegistryToken: registryToken,
}
info, err := docker.DownloadAndExtractDockerImage(util.DefaultContext, image, destination, auth, verify)
if err != nil {
util.DefaultContext.Error(err.Error())
os.Exit(1)
if !local {
info, err := docker.DownloadAndExtractDockerImage(util.DefaultContext, image, destination, auth, verify)
if err != nil {
util.DefaultContext.Error(err.Error())
os.Exit(1)
}
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))))
} else {
info, err := docker.ExtractDockerImage(util.DefaultContext, image, destination)
if err != nil {
util.DefaultContext.Error(err.Error())
os.Exit(1)
}
util.DefaultContext.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))))
},
}
@@ -143,6 +152,32 @@ func NewUnpackCommand() *cobra.Command {
c.Flags().String("auth-identity-token", "", "Authentication identity token")
c.Flags().String("auth-registry-token", "", "Authentication registry token")
c.Flags().Bool("verify", false, "Verify signed images to notary before to pull")
c.Flags().Bool("local", false, "Unpack local image")
return c
}
func NewExistCommand() *cobra.Command {
c := &cobra.Command{
Use: "image-exist image path",
Short: "Check if an image exist",
Long: `Exits 0 if the image exist, otherwise exits with 1`,
PreRun: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
util.DefaultContext.Fatal("Expects an image")
}
},
Run: func(cmd *cobra.Command, args []string) {
if image.Available(args[0]) {
os.Exit(0)
} else {
os.Exit(1)
}
},
}
return c
}
@@ -157,5 +192,6 @@ func init() {
utilGroup.AddCommand(
NewUnpackCommand(),
NewPackCommand(),
NewExistCommand(),
)
}

View File

@@ -16,9 +16,7 @@
package util
import (
"errors"
"os"
"path/filepath"
"strings"
"github.com/marcsauter/single"
@@ -26,28 +24,15 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/api/core/template"
"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"))
viper.BindPFlag("system.database_engine", cmd.Flags().Lookup("system-engine"))
}
func BindSolverFlags(cmd *cobra.Command) {
viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type"))
viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate"))
viper.BindPFlag("solver.max_attempts", cmd.Flags().Lookup("solver-attempts"))
}
func BindValuesFlags(cmd *cobra.Command) {
viper.BindPFlag("values", cmd.Flags().Lookup("values"))
}
@@ -56,62 +41,16 @@ func ValuesFlags() []string {
return viper.GetStringSlice("values")
}
func SetSystemConfig(ctx *types.Context) {
dbpath := viper.GetString("system.database_path")
rootfs := viper.GetString("system.rootfs")
engine := viper.GetString("system.database_engine")
ctx.Config.System.DatabaseEngine = engine
ctx.Config.System.DatabasePath = dbpath
ctx.Config.System.SetRootFS(rootfs)
}
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")
ctx.Config.GetSolverOptions().Type = stype
ctx.Config.GetSolverOptions().LearnRate = float32(rate)
ctx.Config.GetSolverOptions().Discount = float32(discount)
ctx.Config.GetSolverOptions().MaxAttempts = attempts
return &types.LuetSolverOptions{
Type: stype,
LearnRate: float32(rate),
Discount: float32(discount),
MaxAttempts: attempts,
}
}
func SetCliFinalizerEnvs(ctx *types.Context, finalizerEnvs []string) error {
if len(finalizerEnvs) > 0 {
for _, v := range finalizerEnvs {
idx := strings.Index(v, "=")
if idx < 0 {
return errors.New("Found invalid runtime finalizer environment: " + v)
}
ctx.Config.SetFinalizerEnv(v[0:idx], v[idx+1:])
}
}
return nil
}
// TemplateFolders returns the default folders which holds shared template between packages in a given tree path
func TemplateFolders(ctx *types.Context, fromRepo bool, treePaths []string) []string {
func TemplateFolders(ctx *context.Context, i installer.BuildTreeResult, treePaths []string) []string {
templateFolders := []string{}
for _, t := range treePaths {
templateFolders = append(templateFolders, filepath.Join(t, "templates"))
templateFolders = append(templateFolders, template.FindPossibleTemplatesDir(t)...)
}
if fromRepo {
for _, s := range installer.SystemRepositories(ctx.Config.SystemRepositories) {
templateFolders = append(templateFolders, filepath.Join(s.TreePath, "templates"))
}
for _, r := range i.TemplatesDir {
templateFolders = append(templateFolders, r...)
}
return templateFolders
}
@@ -126,7 +65,7 @@ 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) {
func HandleLock(c types.Context) {
if os.Getenv("LUET_NOLOCK") != "true" {
if len(os.Args) > 1 {
for _, lockedCmd := range lockedCommands {
@@ -146,7 +85,7 @@ func HandleLock(c *types.Context) {
}
}
func DisplayVersionBanner(c *types.Context, banner func(), version func() string, license []string) {
func DisplayVersionBanner(c *context.Context, banner func(), version func() string, license []string) {
display := false
if len(os.Args) > 1 {
for _, c := range bannerCommands {

View File

@@ -16,6 +16,7 @@
package util
import (
"errors"
"fmt"
"os"
"os/user"
@@ -23,8 +24,15 @@ import (
"runtime"
"strings"
"github.com/ipfs/go-log/v2"
extensions "github.com/mudler/cobra-extensions"
"github.com/mudler/luet/pkg/api/core/context"
gc "github.com/mudler/luet/pkg/api/core/garbagecollector"
"github.com/mudler/luet/pkg/api/core/logger"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/solver"
"github.com/pterm/pterm"
"go.uber.org/zap/zapcore"
helpers "github.com/mudler/luet/pkg/helpers"
fileHelper "github.com/mudler/luet/pkg/helpers/file"
@@ -87,26 +95,117 @@ func initConfig() {
}
var DefaultContext *context.Context
// 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) {
func InitContext(cmd *cobra.Command) (ctx *context.Context, err error) {
err = viper.Unmarshal(&ctx.Config)
c := &types.LuetConfig{}
err = viper.Unmarshal(c)
if err != nil {
return
}
// Converts user-defined config into paths
// and creates the required directory on the system if necessary
c.Init()
finalizerEnvs, _ := cmd.Flags().GetStringArray("finalizer-env")
setCliFinalizerEnvs(c, finalizerEnvs)
c.Solver.Options = solver.Options{Type: solver.SingleCoreSimple, Concurrency: c.General.Concurrency}
ctx = context.NewContext(
context.WithConfig(c),
context.WithGarbageCollector(gc.GarbageCollector(c.System.TmpDirBase)),
)
// 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
return ctx, initContext(cmd, ctx)
}
func setCliFinalizerEnvs(c *types.LuetConfig, finalizerEnvs []string) error {
if len(finalizerEnvs) > 0 {
for _, v := range finalizerEnvs {
idx := strings.Index(v, "=")
if idx < 0 {
return errors.New("Found invalid runtime finalizer environment: " + v)
}
c.SetFinalizerEnv(v[0:idx], v[idx+1:])
}
}
// no_spinner is not mapped in our configs
ctx.NoSpinner = viper.GetBool("no_spinner")
return nil
}
const (
CommandProcessOutput = "command.process.output"
)
func initContext(cmd *cobra.Command, c *context.Context) (err error) {
if logger.IsTerminal() {
if !c.Config.Logging.Color {
pterm.DisableColor()
}
} else {
pterm.DisableColor()
c.Debug("Not a terminal, colors disabled")
}
if c.Config.General.Quiet {
pterm.DisableColor()
pterm.DisableStyling()
}
level := c.Config.Logging.Level
if c.Config.General.Debug {
level = "debug"
}
if _, ok := cmd.Annotations[CommandProcessOutput]; ok {
// Note: create-repo output is different, so we annotate in the cmd of create-repo CommandNoProcess
// to avoid
out, _ := cmd.Flags().GetString("output")
if out != "terminal" {
level = zapcore.Level(log.LevelFatal).String()
}
}
// Init logging
opts := []logger.LoggerOptions{
logger.WithLevel(level),
}
if c.Config.Logging.NoSpinner {
opts = append(opts, logger.NoSpinner)
}
if c.Config.Logging.EnableLogFile && c.Config.Logging.Path != "" {
f := "console"
if c.Config.Logging.JsonFormat {
f = "json"
}
opts = append(opts, logger.WithFileLogging(c.Config.Logging.Path, f))
}
if c.Config.Logging.EnableEmoji {
opts = append(opts, logger.EnableEmoji())
}
l, err := logger.New(opts...)
c.Logger = l
c.Debug("System rootfs:", c.Config.System.Rootfs)
c.Debug("Colors", c.Config.Logging.Color)
c.Debug("Logging level", c.Config.Logging.Level)
c.Debug("Debug mode", c.Config.General.Debug)
return
}
@@ -121,7 +220,7 @@ func setDefaults(viper *viper.Viper) {
viper.SetDefault("general.concurrency", runtime.NumCPU())
viper.SetDefault("general.debug", false)
viper.SetDefault("general.quiet", false)
viper.SetDefault("general.show_build_output", false)
viper.SetDefault("general.show_build_output", true)
viper.SetDefault("general.fatal_warnings", false)
viper.SetDefault("general.http_timeout", 360)
@@ -156,7 +255,7 @@ func setDefaults(viper *viper.Viper) {
// 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) {
func InitViper(RootCmd *cobra.Command) {
cobra.OnInitialize(initConfig)
pflags := RootCmd.PersistentFlags()
pflags.StringVar(&cfgFile, "config", "", "config file (default is $HOME/.luet.yaml)")
@@ -165,29 +264,39 @@ func InitViper(ctx *types.Context, 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", 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", ctx.Config.GetLogging().Path,
"Logfile path. Empty value disable log to file.")
pflags.Bool("color", true, "Enable/Disable color.")
pflags.Bool("emoji", true, "Enable/Disable emoji.")
pflags.Bool("skip-config-protect", true, "Disable config protect analysis.")
pflags.StringP("logfile", "l", "", "Logfile path. Empty value disable log to file.")
pflags.StringSlice("plugin", []string{}, "A list of runtime plugins to load")
// os/user doesn't work in from scratch environments.
// Check if i can retrieve user informations.
_, err := user.Current()
if err != nil {
ctx.Warning("failed to retrieve user identity:", err.Error())
}
pflags.Bool("same-owner", ctx.Config.GetGeneral().SameOwner, "Maintain same owner on uncompress.")
pflags.String("system-dbpath", "", "System db path")
pflags.String("system-target", "", "System rootpath")
pflags.String("system-engine", "", "System DB engine")
pflags.String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )")
pflags.Float32("solver-rate", 0.7, "Solver learning rate")
pflags.Float32("solver-discount", 1.0, "Solver discount rate")
pflags.Int("solver-attempts", 9000, "Solver maximum attempts")
pflags.Bool("live-output", true, "Show live output during build")
pflags.Bool("same-owner", true, "Maintain same owner on uncompress.")
pflags.Int("concurrency", runtime.NumCPU(), "Concurrency")
pflags.Int("http-timeout", ctx.Config.General.HTTPTimeout, "Default timeout for http(s) requests")
pflags.Int("http-timeout", 360, "Default timeout for http(s) requests")
viper.BindPFlag("system.database_path", pflags.Lookup("system-dbpath"))
viper.BindPFlag("system.rootfs", pflags.Lookup("system-target"))
viper.BindPFlag("system.database_engine", pflags.Lookup("system-engine"))
viper.BindPFlag("solver.type", pflags.Lookup("solver-type"))
viper.BindPFlag("solver.discount", pflags.Lookup("solver-discount"))
viper.BindPFlag("solver.rate", pflags.Lookup("solver-rate"))
viper.BindPFlag("solver.max_attempts", pflags.Lookup("solver-attempts"))
viper.BindPFlag("logging.color", pflags.Lookup("color"))
viper.BindPFlag("logging.enable_emoji", pflags.Lookup("emoji"))
viper.BindPFlag("logging.enable_logfile", pflags.Lookup("enable-logfile"))
viper.BindPFlag("logging.path", pflags.Lookup("logfile"))
viper.BindPFlag("logging.no_spinner", pflags.Lookup("no-spinner"))
viper.BindPFlag("general.concurrency", pflags.Lookup("concurrency"))
viper.BindPFlag("general.debug", pflags.Lookup("debug"))
viper.BindPFlag("general.quiet", pflags.Lookup("quiet"))
@@ -195,6 +304,7 @@ func InitViper(ctx *types.Context, RootCmd *cobra.Command) {
viper.BindPFlag("general.same_owner", pflags.Lookup("same-owner"))
viper.BindPFlag("plugin", pflags.Lookup("plugin"))
viper.BindPFlag("general.http_timeout", pflags.Lookup("http-timeout"))
viper.BindPFlag("general.show_build_output", pflags.Lookup("live-output"))
// Currently I maintain this only from cli.
viper.BindPFlag("no_spinner", pflags.Lookup("no-spinner"))

23
go.mod
View File

@@ -10,32 +10,33 @@ require (
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
github.com/asdine/storm v0.0.0-20190418133842-e0f77eada154
github.com/cavaliercoder/grab v1.0.1-0.20201108051000-98a5bfe305ec
github.com/containerd/containerd v1.5.2
github.com/containerd/containerd v1.5.7
github.com/crillab/gophersat v1.3.2-0.20210701121804-72b19f5b6b38
github.com/docker/cli v20.10.7+incompatible
github.com/docker/cli v20.10.10+incompatible
github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker v20.10.7+incompatible
github.com/docker/docker v20.10.10+incompatible
github.com/docker/go-units v0.4.0
github.com/ecooper/qlearning v0.0.0-20160612200101-3075011a69fd
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/ghodss/yaml v1.0.0
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/go-containerregistry v0.6.0
github.com/google/go-containerregistry v0.7.0
github.com/google/renameio v1.0.0
github.com/google/uuid v1.3.0 // indirect
github.com/gookit/color v1.5.0
github.com/gorilla/mux v1.7.4 // indirect
github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/go-version v1.3.0
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12
github.com/ipfs/go-log/v2 v2.4.0
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
github.com/klauspost/compress v1.13.0
github.com/klauspost/compress v1.13.6
github.com/klauspost/pgzip v1.2.5
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
github.com/kyokomi/emoji v2.1.0+incompatible
github.com/marcsauter/single v0.0.0-20181104081128-f8bf46f26ec0
github.com/mattn/go-isatty v0.0.14
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.1
github.com/mitchellh/mapstructure v1.4.2 // indirect
@@ -44,10 +45,10 @@ require (
github.com/mudler/cobra-extensions v0.0.0-20200612154940-31a47105fe3d
github.com/mudler/go-pluggable v0.0.0-20211206135551-9263b05c562e
github.com/mudler/topsort v0.0.0-20201103161459-db5c7901c290
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.16.0
github.com/onsi/ginkgo/v2 v2.0.0
github.com/onsi/gomega v1.17.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7
github.com/otiai10/copy v1.2.1-0.20200916181228-26f84a0b1578
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible
@@ -64,12 +65,8 @@ require (
go.uber.org/zap v1.17.0
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/mod v0.4.2
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 // indirect
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
google.golang.org/genproto v0.0.0-20210811021853-ddbe55d93216 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.63.2 // indirect
gopkg.in/yaml.v2 v2.4.0
helm.sh/helm/v3 v3.3.4

134
go.sum
View File

@@ -20,6 +20,12 @@ cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECH
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -89,16 +95,17 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
github.com/Microsoft/hcsshim v0.8.16 h1:8/auA4LFIZFTGrqfKhGBSXwM6/4X1fHa/xniyEHu8ac=
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
github.com/Microsoft/hcsshim v0.8.21 h1:btRfUDThBE5IKcvI8O8jOiIkujUsAMBSRsYDYmEi6oM=
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
github.com/MottainaiCI/simplestreams-builder v0.1.0/go.mod h1:+Gbv6dg6TPHWq4oDjZY1vn978PLCEZ2hOu8kvn+S7t4=
@@ -157,6 +164,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
@@ -182,6 +190,7 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4=
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@@ -191,6 +200,7 @@ github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmE
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ=
@@ -198,7 +208,11 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
@@ -234,8 +248,9 @@ github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7
github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
github.com/containerd/containerd v1.5.2 h1:MG/Bg1pbmMb61j3wHCFWPxESXHieiKr2xG64px/k8zQ=
github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.7 h1:rQyoYtj4KddB3bxG6SAqd4+08gePNyJjRqvOIfV3rkM=
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@@ -265,8 +280,8 @@ github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJ
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/stargz-snapshotter/estargz v0.7.0 h1:1d/rydzTywc76lnjJb6qbPCiTiCwts49AzKps/Ecblw=
github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw=
github.com/containerd/stargz-snapshotter/estargz v0.10.0 h1:glqzafvxBBAMo+x2w2sdDjUDZeTqqLJmqZPY05qehCU=
github.com/containerd/stargz-snapshotter/estargz v0.10.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
@@ -310,6 +325,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/crillab/gophersat v1.3.2-0.20210701121804-72b19f5b6b38 h1:sOsE90v/iPmouqh4d3cKQl8JuqTOEXg+fP+7YuY7R6U=
@@ -320,6 +336,7 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -333,8 +350,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v20.10.7+incompatible h1:pv/3NqibQKphWZiAskMzdz8w0PRbtTaEB+f6NwdU7Is=
github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v20.10.10+incompatible h1:kcbwdgWbrBOH8QwQzaJmyriHwF7XIl4HT1qh0HTRys4=
github.com/docker/cli v20.10.10+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
@@ -342,10 +359,11 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
github.com/docker/docker v20.10.10+incompatible h1:GKkP0T7U4ks6X3lmmHKC2QDprnpRJor2Z5a8m62R9ZM=
github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@@ -383,6 +401,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc=
@@ -511,6 +530,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -554,8 +574,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-containerregistry v0.6.0 h1:niQ+8XD//kKgArIFwDVBXsWVWbde16LPdHMyNwSC8h4=
github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw=
github.com/google/go-containerregistry v0.7.0 h1:u0onUUOcyoCDHEiJoyR1R1gx5er1+r06V5DBhUU5ndk=
github.com/google/go-containerregistry v0.7.0/go.mod h1:2zaoelrL0d08gGbpdP3LqyUuBmhWbpD6IOe2s9nLS2k=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -574,7 +594,10 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/renameio v1.0.0 h1:xhp2CnJmgQmpJU4RY8chagahUq5mbPPAbiSQstKpVMA=
github.com/google/renameio v1.0.0/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
@@ -586,6 +609,7 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
@@ -601,8 +625,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@@ -663,6 +687,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/ipfs/go-log/v2 v2.4.0 h1:iR/2o9PGWanVJrBgIH5Ff8mPGOwpqLaPIAFqSnsdlzk=
github.com/ipfs/go-log/v2 v2.4.0/go.mod h1:nPZnh7Cj7lwS3LpRU5Mwr2ol1c2gXIEXuF6aywqrtmo=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3 h1:sHsPfNMAG70QAvKbddQ0uScZCHQoZsT5NykGRCeeeIs=
@@ -696,9 +722,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.0 h1:2T7tUoQrQT+fQWdaY5rjWztFGAFwbGD04iPJg90ZiOs=
github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d h1:X4cedH4Kn3JPupAwwWuo4AzYp16P0OyLO9d7OnMZc/c=
@@ -747,6 +772,8 @@ github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHef
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-oci8 v0.0.7/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
@@ -848,6 +875,8 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -857,8 +886,9 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
github.com/onsi/gomega v1.10.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -867,22 +897,26 @@ github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7 h1:axgApq2XShTLwQii2zAnIkMPlhGVHbAXHUcHezu5G/k=
github.com/opencontainers/image-spec v1.0.2-0.20210730191737-8e42a01fb1b7/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
@@ -1079,6 +1113,9 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
@@ -1139,15 +1176,18 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1269,9 +1309,9 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211111160137-58aab5ef257a h1:c83jeVQW0KGKNaKBRfelNYNHaev+qawl9yaA825s8XE=
golang.org/x/net v0.0.0-20211111160137-58aab5ef257a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1285,8 +1325,11 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 h1:Ati8dO7+U7mxpkPSxBZQEvzHVUYB/MqCklCN8ig5w/o=
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1385,14 +1428,19 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 h1:WecRHqgE09JBkh/584XIE6PMz5KKE/vER4izNUi30AQ=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1483,6 +1531,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1514,6 +1564,12 @@ google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBz
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1570,8 +1626,21 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210811021853-ddbe55d93216 h1:qnrhhl4uoNFepTqE28u11llFcDH07Z6r/cQxpGR97A4=
google.golang.org/genproto v0.0.0-20210811021853-ddbe55d93216/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211111162719-482062a4217b h1:qvEQEwKjZRAg6rjY/jqfJ7T8/w/D7jTIFJGcaSka96k=
google.golang.org/genproto v0.0.0-20211111162719-482062a4217b/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -1602,8 +1671,11 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.39.1 h1:f37vZbBVTiJ6jKG5mWz8ySOBxNqy6ViPgyhSdVnxF3E=
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

View File

@@ -18,7 +18,7 @@ package client_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -20,8 +20,8 @@ import (
"fmt"
"strings"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/mudler/luet/pkg/api/client/utils"
image "github.com/mudler/luet/pkg/api/core/image"
)
func TreePackages(treedir string) (searchResult SearchResult, err error) {
@@ -35,11 +35,6 @@ func TreePackages(treedir string) (searchResult SearchResult, err error) {
return
}
func imageAvailable(image string) bool {
_, err := crane.Digest(image)
return err == nil
}
type SearchResult struct {
Packages []Package
}
@@ -66,7 +61,7 @@ func (p Package) ImageMetadata(repository string) string {
}
func (p Package) ImageAvailable(repository string) bool {
return imageAvailable(p.Image(repository))
return image.Available(p.Image(repository))
}
func (p Package) Equal(pp Package) bool {

View File

@@ -17,7 +17,7 @@ package client_test
import (
. "github.com/mudler/luet/pkg/api/client"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -90,7 +90,7 @@ type Bus struct {
*pluggable.Manager
}
func (b *Bus) Initialize(ctx *types.Context, plugin ...string) {
func (b *Bus) Initialize(ctx types.Context, plugin ...string) {
b.Manager.Load(plugin...).Register()
for _, e := range b.Manager.Events {

View File

@@ -18,9 +18,9 @@ package config_test
import (
config "github.com/mudler/luet/pkg/api/core/config"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -29,7 +29,7 @@ var _ = Describe("Config", func() {
Context("Test config protect", func() {
It("Protect1", func() {
ctx := types.NewContext()
ctx := context.NewContext()
files := []string{
"etc/foo/my.conf",
"usr/bin/foo",
@@ -59,7 +59,7 @@ var _ = Describe("Config", func() {
})
It("Protect2", func() {
ctx := types.NewContext()
ctx := context.NewContext()
files := []string{
"etc/foo/my.conf",
@@ -86,7 +86,7 @@ var _ = Describe("Config", func() {
})
It("Protect3: Annotation dir without initial slash", func() {
ctx := types.NewContext()
ctx := context.NewContext()
files := []string{
"etc/foo/my.conf",

View File

@@ -19,7 +19,7 @@ package config_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -0,0 +1,28 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package context_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestContext(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Context Suite")
}

View File

@@ -0,0 +1,159 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package context
import (
"context"
"os"
"path/filepath"
fileHelper "github.com/mudler/luet/pkg/helpers/file"
gc "github.com/mudler/luet/pkg/api/core/garbagecollector"
"github.com/mudler/luet/pkg/api/core/logger"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/pkg/errors"
)
type Context struct {
*logger.Logger
context.Context
types.GarbageCollector
Config *types.LuetConfig
NoSpinner bool
annotations map[string]interface{}
}
// SetAnnotation sets generic annotations to hold in a context
func (c *Context) SetAnnotation(s string, i interface{}) {
c.annotations[s] = i
}
// GetAnnotation gets generic annotations to hold in a context
func (c *Context) GetAnnotation(s string) interface{} {
return c.annotations[s]
}
type ContextOption func(c *Context) error
// WithLogger sets the logger
func WithLogger(l *logger.Logger) ContextOption {
return func(c *Context) error {
c.Logger = l
return nil
}
}
// WithConfig sets the luet config
func WithConfig(cc *types.LuetConfig) ContextOption {
return func(c *Context) error {
c.Config = cc
return nil
}
}
// NOTE: GC needs to be instantiated when a new context is created from system TmpDirBase
// WithGarbageCollector sets the Garbage collector for the given context
func WithGarbageCollector(l types.GarbageCollector) ContextOption {
return func(c *Context) error {
if !filepath.IsAbs(l.String()) {
abs, err := fileHelper.Rel2Abs(l.String())
if err != nil {
return errors.Wrap(err, "while converting relative path to absolute path")
}
l = gc.GarbageCollector(abs)
}
c.GarbageCollector = l
return nil
}
}
// NewContext returns a new context.
// It accepts a Garbage collector, a config and a logger as an option
func NewContext(opts ...ContextOption) *Context {
l, _ := logger.New()
d := &Context{
annotations: make(map[string]interface{}),
Logger: l,
GarbageCollector: gc.GarbageCollector(filepath.Join(os.TempDir(), "tmpluet")),
Config: &types.LuetConfig{
ConfigFromHost: true,
Logging: types.LuetLoggingConfig{},
General: types.LuetGeneralConfig{},
System: types.LuetSystemConfig{
DatabasePath: filepath.Join("var", "db"),
PkgsCachePath: filepath.Join("var", "db", "packages"),
},
Solver: types.LuetSolverOptions{},
},
}
for _, o := range opts {
o(d)
}
return d
}
// WithLoggingContext returns a copy of the context with a contextualized logger
func (c *Context) WithLoggingContext(name string) types.Context {
configCopy := *c.Config
configCopy.System = c.Config.System
configCopy.General = c.Config.General
configCopy.Logging = c.Config.Logging
ctx := *c
ctxCopy := &ctx
ctxCopy.Config = &configCopy
ctxCopy.annotations = ctx.annotations
ctxCopy.Logger, _ = c.Logger.Copy(logger.WithContext(name))
return ctxCopy
}
// Copy returns a context copy with a reset logging context
func (c *Context) Copy() types.Context {
return c.WithLoggingContext("")
}
func (c *Context) Warning(mess ...interface{}) {
c.Logger.Warn(mess...)
if c.Config.General.FatalWarns {
os.Exit(2)
}
}
func (c *Context) Warn(mess ...interface{}) {
c.Warning(mess...)
}
func (c *Context) Warnf(t string, mess ...interface{}) {
c.Logger.Warnf(t, mess...)
if c.Config.General.FatalWarns {
os.Exit(2)
}
}
func (c *Context) Warningf(t string, mess ...interface{}) {
c.Warnf(t, mess...)
}
func (c *Context) GetConfig() types.LuetConfig {
return *c.Config
}

View File

@@ -0,0 +1,59 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package gc
import (
"io/ioutil"
"os"
)
type GarbageCollector string
func (c GarbageCollector) String() string {
return string(c)
}
func (c GarbageCollector) init() error {
if _, err := os.Stat(string(c)); err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(string(c), os.ModePerm)
if err != nil {
return err
}
}
}
return nil
}
func (c GarbageCollector) Clean() error {
return os.RemoveAll(string(c))
}
func (c GarbageCollector) TempDir(pattern string) (string, error) {
err := c.init()
if err != nil {
return "", err
}
return ioutil.TempDir(string(c), pattern)
}
func (c GarbageCollector) TempFile(s string) (*os.File, error) {
err := c.init()
if err != nil {
return nil, err
}
return ioutil.TempFile(string(c), s)
}

View File

@@ -18,25 +18,25 @@ package image_test
import (
"path/filepath"
"github.com/mudler/luet/pkg/api/core/context"
. "github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/helpers/file"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Cache", func() {
ctx := types.NewContext()
ctx := context.NewContext()
Context("used as k/v store", func() {
cache := &Cache{}
var dir string
BeforeEach(func() {
ctx = types.NewContext()
ctx = context.NewContext()
var err error
dir, err = ctx.Config.System.TempDir("foo")
dir, err = ctx.TempDir("foo")
Expect(err).ToNot(HaveOccurred())
cache = NewCache(dir, 10*1024*1024, 1) // 10MB Cache when upgrading to files. Max volatile memory of 1 row.
})

View File

@@ -20,24 +20,24 @@ import (
"path/filepath"
"runtime"
"github.com/mudler/luet/pkg/api/core/context"
. "github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/types/artifact"
"github.com/mudler/luet/pkg/compiler/backend"
"github.com/mudler/luet/pkg/helpers/file"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Create", func() {
Context("Creates an OCI image from a standard tar", func() {
It("creates an image which is loadable", func() {
ctx := types.NewContext()
ctx := context.NewContext()
dst, err := ctx.Config.System.TempFile("dst")
dst, err := ctx.TempFile("dst")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(dst.Name())
srcTar, err := ctx.Config.System.TempFile("srcTar")
srcTar, err := ctx.TempFile("srcTar")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(srcTar.Name())

View File

@@ -23,10 +23,10 @@ import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
daemon "github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/mudler/luet/pkg/api/core/context"
. "github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/helpers/file"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -47,7 +47,7 @@ var _ = Describe("Delta", func() {
})
Context("ExtractDeltaFiles", func() {
ctx := types.NewContext()
ctx := context.NewContext()
var tmpfile *os.File
var ref, ref2 name.Reference
var img, img2 v1.Image
@@ -59,7 +59,7 @@ var _ = Describe("Delta", func() {
img2, _ = daemon.Image(ref2)
BeforeEach(func() {
ctx = types.NewContext()
ctx = context.NewContext()
tmpfile, err = ioutil.TempFile("", "delta")
Expect(err).ToNot(HaveOccurred())
@@ -78,9 +78,14 @@ var _ = Describe("Delta", func() {
)
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmpdir) // clean up
// No extra dirs are present
Expect(file.Exists(filepath.Join(tmpdir, "home"))).To(BeFalse())
// Cache from go
Expect(file.Exists(filepath.Join(tmpdir, "root", ".cache"))).To(BeTrue())
// sh is present from alpine, hence not in the result
Expect(file.Exists(filepath.Join(tmpdir, "bin", "sh"))).To(BeFalse())
// /usr/local/go is part of golang:alpine
Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go"))).To(BeTrue())
Expect(file.Exists(filepath.Join(tmpdir, "usr", "local", "go", "bin"))).To(BeTrue())
})

View File

@@ -0,0 +1,42 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package image
import (
"crypto/tls"
"net/http"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/google/go-containerregistry/pkg/v1/remote"
)
// Available checks if the image is available in the remote endpoint.
func Available(image string, opt ...crane.Option) bool {
// We use crane.insecure as we just check if the image is available
// It's the daemon duty to use it or not based on the host settings
transport := remote.DefaultTransport.Clone()
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true, //nolint: gosec
}
var rt http.RoundTripper = transport
if len(opt) == 0 {
opt = append(opt, crane.Insecure, crane.WithTransport(rt))
}
_, err := crane.Digest(image, opt...)
return err == nil
}

View File

@@ -35,7 +35,7 @@ import (
// considering the added files only, and applies a filter on them based on the regexes
// in the lists.
func ExtractDeltaAdditionsFiles(
ctx *types.Context,
ctx types.Context,
srcimg v1.Image,
includes []string, excludes []string,
) (func(h *tar.Header) (bool, error), error) {
@@ -43,7 +43,7 @@ func ExtractDeltaAdditionsFiles(
includeRegexp := compileRegexes(includes)
excludeRegexp := compileRegexes(excludes)
srcfilesd, err := ctx.Config.System.TempDir("srcfiles")
srcfilesd, err := ctx.TempDir("srcfiles")
if err != nil {
return nil, err
}
@@ -65,12 +65,7 @@ func ExtractDeltaAdditionsFiles(
return nil, err
}
switch hdr.Typeflag {
case tar.TypeDir:
filesSrc.Set(filepath.Dir(hdr.Name), "")
default:
filesSrc.Set(hdr.Name, "")
}
filesSrc.Set(hdr.Name, "")
}
return func(h *tar.Header) (bool, error) {
@@ -128,7 +123,7 @@ func ExtractDeltaAdditionsFiles(
// It then filters files by an include and exclude list.
// The list can be regexes
func ExtractFiles(
ctx *types.Context,
ctx types.Context,
prefixPath string,
includes []string, excludes []string,
) func(h *tar.Header) (bool, error) {
@@ -193,7 +188,7 @@ func ExtractFiles(
// ExtractReader perform the extracting action over the io.ReadCloser
// it extracts the files over output. Accepts a filter as an option
// and additional containerd Options
func ExtractReader(ctx *types.Context, reader io.ReadCloser, output string, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (int64, string, error) {
func ExtractReader(ctx types.Context, reader io.ReadCloser, output string, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (int64, string, error) {
defer reader.Close()
// If no filter is specified, grab all.
@@ -213,8 +208,8 @@ func ExtractReader(ctx *types.Context, reader io.ReadCloser, output string, filt
}
// Extract is just syntax sugar around ExtractReader. It extracts an image into a dir
func Extract(ctx *types.Context, img v1.Image, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (int64, string, error) {
tmpdiffs, err := ctx.Config.GetSystem().TempDir("extraction")
func Extract(ctx types.Context, img v1.Image, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (int64, string, error) {
tmpdiffs, err := ctx.TempDir("extraction")
if err != nil {
return 0, "", errors.Wrap(err, "Error met while creating tempdir for rootfs")
}
@@ -222,6 +217,6 @@ func Extract(ctx *types.Context, img v1.Image, filter func(h *tar.Header) (bool,
}
// ExtractTo is just syntax sugar around ExtractReader
func ExtractTo(ctx *types.Context, img v1.Image, output string, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (int64, string, error) {
func ExtractTo(ctx types.Context, img v1.Image, output string, filter func(h *tar.Header) (bool, error), opts ...containerdarchive.ApplyOpt) (int64, string, error) {
return ExtractReader(ctx, mutate.Extract(img), output, filter, opts...)
}

View File

@@ -23,10 +23,10 @@ import (
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
daemon "github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/mudler/luet/pkg/api/core/context"
. "github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/helpers/file"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -34,14 +34,14 @@ var _ = Describe("Extract", func() {
Context("extract files from images", func() {
Context("ExtractFiles", func() {
ctx := types.NewContext()
ctx := context.NewContext()
var tmpfile *os.File
var ref name.Reference
var img v1.Image
var err error
BeforeEach(func() {
ctx = types.NewContext()
ctx = context.NewContext()
tmpfile, err = ioutil.TempFile("", "extract")
Expect(err).ToNot(HaveOccurred())

View File

@@ -18,17 +18,17 @@ package image_test
import (
"testing"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/compiler/backend"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestMutator(t *testing.T) {
func TestImageApi(t *testing.T) {
RegisterFailHandler(Fail)
b := backend.NewSimpleDockerBackend(types.NewContext())
b := backend.NewSimpleDockerBackend(context.NewContext())
b.DownloadImage(backend.Options{ImageName: "alpine"})
b.DownloadImage(backend.Options{ImageName: "golang:alpine"})
RunSpecs(t, "Mutator API Suite")
RunSpecs(t, "Image API Suite")
}

View File

@@ -0,0 +1,28 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package logger_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestAPITypes(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Types Suite")
}

View File

@@ -0,0 +1,367 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package logger
import (
"fmt"
"os"
"path"
"regexp"
"runtime"
"strings"
"sync"
log "github.com/ipfs/go-log/v2"
"github.com/kyokomi/emoji"
"github.com/pterm/pterm"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// Logger is the default logger
type Logger struct {
level log.LogLevel
emoji bool
logToFile bool
noSpinner bool
fileLogger *zap.Logger
context string
spinnerLock sync.Mutex
s *pterm.SpinnerPrinter
}
// LogLevel represents a log severity level. Use the package variables as an
// enum.
type LogLevel zapcore.Level
type LoggerOptions func(*Logger) error
var NoSpinner LoggerOptions = func(l *Logger) error {
l.noSpinner = true
return nil
}
func WithLevel(level string) LoggerOptions {
return func(l *Logger) error {
lvl, _ := log.LevelFromString(level) // Defaults to Info
l.level = lvl
if l.level == log.LevelDebug {
pterm.EnableDebugMessages()
}
return nil
}
}
func WithContext(c string) LoggerOptions {
return func(l *Logger) error {
l.context = c
return nil
}
}
func WithFileLogging(p, encoding string) LoggerOptions {
return func(l *Logger) error {
if encoding == "" {
encoding = "console"
}
l.logToFile = true
var err error
cfg := zap.NewProductionConfig()
cfg.OutputPaths = []string{p}
cfg.Level = zap.NewAtomicLevelAt(zapcore.Level(l.level))
cfg.ErrorOutputPaths = []string{}
cfg.Encoding = encoding
cfg.DisableCaller = true
cfg.DisableStacktrace = true
cfg.EncoderConfig.TimeKey = "time"
cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
l.fileLogger, err = cfg.Build()
return err
}
}
var EnableEmoji = func() LoggerOptions {
return func(l *Logger) error {
l.emoji = true
return nil
}
}
func New(opts ...LoggerOptions) (*Logger, error) {
l := &Logger{
level: log.LevelDebug,
s: pterm.DefaultSpinner.WithShowTimer(false).WithRemoveWhenDone(true),
}
for _, o := range opts {
if err := o(l); err != nil {
return nil, err
}
}
return l, nil
}
func (l *Logger) Copy(opts ...LoggerOptions) (*Logger, error) {
c := *l
copy := &c
for _, o := range opts {
if err := o(copy); err != nil {
return nil, err
}
}
return copy, nil
}
func joinMsg(args ...interface{}) (message string) {
for _, m := range args {
message += " " + fmt.Sprintf("%v", m)
}
return
}
func (l *Logger) enabled(lvl log.LogLevel) bool {
return lvl >= l.level
}
var emojiStrip = regexp.MustCompile(`[:][\w]+[:]`)
func (l *Logger) transform(args ...interface{}) (sanitized []interface{}) {
for _, a := range args {
var aString string
// Strip emoji if needed
if l.emoji {
aString = emoji.Sprint(a)
} else {
aString = emojiStrip.ReplaceAllString(joinMsg(a), "")
}
sanitized = append(sanitized, aString)
}
if l.context != "" {
sanitized = append([]interface{}{fmt.Sprintf("(%s)", l.context)}, sanitized...)
}
return
}
func prefixCodeLine(args ...interface{}) []interface{} {
pc, file, line, ok := runtime.Caller(3)
if ok {
args = append([]interface{}{fmt.Sprintf("(%s:#%d:%v)",
path.Base(file), line, runtime.FuncForPC(pc).Name())}, args...)
}
return args
}
func (l *Logger) send(ll log.LogLevel, f string, args ...interface{}) {
if !l.enabled(ll) {
return
}
sanitizedArgs := joinMsg(l.transform(args...)...)
sanitizedF := joinMsg(l.transform(f)...)
formatDefined := f != ""
switch {
case log.LevelDebug == ll && !formatDefined:
pterm.Debug.Println(prefixCodeLine(sanitizedArgs)...)
if l.logToFile {
l.fileLogger.Debug(joinMsg(prefixCodeLine(sanitizedArgs)...))
}
case log.LevelDebug == ll && formatDefined:
pterm.Debug.Printfln(joinMsg(prefixCodeLine(sanitizedF)...), args...)
if l.logToFile {
l.fileLogger.Sugar().Debugf(joinMsg(prefixCodeLine(sanitizedF)...), args...)
}
case log.LevelError == ll && !formatDefined:
pterm.Error.Println(pterm.LightRed(sanitizedArgs))
if l.logToFile {
l.fileLogger.Error(sanitizedArgs)
}
case log.LevelError == ll && formatDefined:
pterm.Error.Printfln(pterm.LightRed(sanitizedF), args...)
if l.logToFile {
l.fileLogger.Sugar().Errorf(sanitizedF, args...)
}
case log.LevelFatal == ll && !formatDefined:
pterm.Error.Println(sanitizedArgs)
if l.logToFile {
l.fileLogger.Error(sanitizedArgs)
}
case log.LevelFatal == ll && formatDefined:
pterm.Error.Printfln(sanitizedF, args...)
if l.logToFile {
l.fileLogger.Sugar().Errorf(sanitizedF, args...)
}
//INFO
case log.LevelInfo == ll && !formatDefined:
pterm.Info.Println(sanitizedArgs)
if l.logToFile {
l.fileLogger.Info(sanitizedArgs)
}
case log.LevelInfo == ll && formatDefined:
pterm.Info.Printfln(sanitizedF, args...)
if l.logToFile {
l.fileLogger.Sugar().Infof(sanitizedF, args...)
}
//WARN
case log.LevelWarn == ll && !formatDefined:
pterm.Warning.Println(sanitizedArgs)
if l.logToFile {
l.fileLogger.Warn(sanitizedArgs)
}
case log.LevelWarn == ll && formatDefined:
pterm.Warning.Printfln(sanitizedF, args...)
if l.logToFile {
l.fileLogger.Sugar().Warnf(sanitizedF, args...)
}
}
}
func (l *Logger) Debug(args ...interface{}) {
l.send(log.LevelDebug, "", args...)
}
func (l *Logger) Error(args ...interface{}) {
l.send(log.LevelError, "", args...)
}
func (l *Logger) Trace(args ...interface{}) {
l.send(log.LevelDebug, "", args...)
}
func (l *Logger) Tracef(t string, args ...interface{}) {
l.send(log.LevelDebug, t, args...)
}
func (l *Logger) Fatal(args ...interface{}) {
l.send(log.LevelFatal, "", args...)
os.Exit(1)
}
func (l *Logger) Info(args ...interface{}) {
l.send(log.LevelInfo, "", args...)
}
func (l *Logger) Success(args ...interface{}) {
l.Info(append([]interface{}{"SUCCESS"}, args...)...)
}
func (l *Logger) Panic(args ...interface{}) {
l.Fatal(args...)
}
func (l *Logger) Warn(args ...interface{}) {
l.send(log.LevelWarn, "", args...)
}
func (l *Logger) Warning(args ...interface{}) {
l.Warn(args...)
}
func (l *Logger) Debugf(f string, args ...interface{}) {
l.send(log.LevelDebug, f, args...)
}
func (l *Logger) Errorf(f string, args ...interface{}) {
l.send(log.LevelError, f, args...)
}
func (l *Logger) Fatalf(f string, args ...interface{}) {
l.send(log.LevelFatal, f, args...)
}
func (l *Logger) Infof(f string, args ...interface{}) {
l.send(log.LevelInfo, f, args...)
}
func (l *Logger) Panicf(f string, args ...interface{}) {
l.Fatalf(joinMsg(f), args...)
}
func (l *Logger) Warnf(f string, args ...interface{}) {
l.send(log.LevelWarn, f, args...)
}
func (l *Logger) Warningf(f string, args ...interface{}) {
l.Warnf(f, args...)
}
func (l *Logger) Ask() bool {
var input string
l.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
}
// Spinner starts the spinner
func (l *Logger) Spinner() {
if !IsTerminal() || l.noSpinner {
return
}
l.spinnerLock.Lock()
defer l.spinnerLock.Unlock()
if l.s != nil && !l.s.IsActive {
l.s, _ = l.s.Start()
}
}
func (l *Logger) Screen(text string) {
pterm.DefaultHeader.WithBackgroundStyle(pterm.NewStyle(pterm.BgLightBlue)).WithMargin(2).Println(text)
}
func (l *Logger) SpinnerText(suffix, prefix string) {
if !IsTerminal() || l.noSpinner {
return
}
l.spinnerLock.Lock()
defer l.spinnerLock.Unlock()
if l.level == log.LevelDebug {
fmt.Printf("%s %s\n",
suffix, prefix,
)
} else {
l.s.UpdateText(suffix + prefix)
}
}
func (l *Logger) SpinnerStop() {
if !IsTerminal() || l.noSpinner {
return
}
l.spinnerLock.Lock()
defer l.spinnerLock.Unlock()
if l.s != nil {
l.s.Success()
}
}

View File

@@ -13,7 +13,7 @@
// You should have received a copy of the GNU General Public License along
// with this program; if not, see <http://www.gnu.org/licenses/>.
package types_test
package logger_test
import (
"io"
@@ -21,8 +21,9 @@ import (
"os"
"github.com/gookit/color"
types "github.com/mudler/luet/pkg/api/core/types"
. "github.com/onsi/ginkgo"
"github.com/mudler/luet/pkg/api/core/logger"
. "github.com/mudler/luet/pkg/api/core/logger"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -44,30 +45,11 @@ func captureStdout(f func(w io.Writer)) string {
}
var _ = Describe("Context and logging", func() {
ctx := types.NewContext()
BeforeEach(func() {
ctx = types.NewContext()
})
Context("LogLevel", func() {
It("converts it correctly to number and zaplog", func() {
Expect(types.ErrorLevel.ToNumber()).To(Equal(0))
Expect(types.InfoLevel.ToNumber()).To(Equal(2))
Expect(types.WarningLevel.ToNumber()).To(Equal(1))
Expect(types.LogLevel("foo").ToNumber()).To(Equal(3))
Expect(types.WarningLevel.ZapLevel().String()).To(Equal("warn"))
Expect(types.InfoLevel.ZapLevel().String()).To(Equal("info"))
Expect(types.ErrorLevel.ZapLevel().String()).To(Equal("error"))
Expect(types.FatalLevel.ZapLevel().String()).To(Equal("fatal"))
Expect(types.LogLevel("foo").ZapLevel().String()).To(Equal("debug"))
})
})
Context("Context", func() {
It("detect if is a terminal", func() {
Expect(captureStdout(func(w io.Writer) {
_, _, err := ctx.GetTerminalSize()
_, _, err := GetTerminalSize()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal("size not detectable"))
os.Stdout.Write([]byte(err.Error()))
@@ -75,47 +57,71 @@ var _ = Describe("Context and logging", func() {
})
It("respects loglevel", func() {
ctx.Config.GetGeneral().Debug = false
l, err := New(WithLevel("info"))
Expect(err).ToNot(HaveOccurred())
Expect(captureStdout(func(w io.Writer) {
ctx.Debug("")
l.Debug("")
})).To(Equal(""))
ctx.Config.GetGeneral().Debug = true
l, err = New(WithLevel("debug"))
Expect(err).ToNot(HaveOccurred())
Expect(captureStdout(func(w io.Writer) {
ctx.Debug("foo")
l.Debug("foo")
})).To(ContainSubstring("foo"))
})
It("logs with context", func() {
l, err := New(WithLevel("debug"), WithContext("foo"))
Expect(err).ToNot(HaveOccurred())
Expect(captureStdout(func(w io.Writer) {
l.Debug("bar")
})).To(ContainSubstring("(foo) bar"))
})
It("returns copies with logged context", func() {
l, err := New(WithLevel("debug"))
l, _ = l.Copy(logger.WithContext("bazzz"))
Expect(err).ToNot(HaveOccurred())
Expect(captureStdout(func(w io.Writer) {
l.Debug("bar")
})).To(ContainSubstring("(bazzz) bar"))
})
It("logs to file", func() {
ctx.NoColor()
t, err := ioutil.TempFile("", "tree")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(t.Name()) // clean up
ctx.Config.GetLogging().EnableLogFile = true
ctx.Config.GetLogging().Path = t.Name()
ctx.Init()
l, err := New(WithLevel("debug"), WithFileLogging(t.Name(), ""))
Expect(err).ToNot(HaveOccurred())
// ctx.Init()
Expect(captureStdout(func(w io.Writer) {
ctx.Info("foot")
l.Info("foot")
})).To(And(ContainSubstring("INFO"), ContainSubstring("foot")))
Expect(captureStdout(func(w io.Writer) {
ctx.Success("test")
l.Success("test")
})).To(And(ContainSubstring("SUCCESS"), ContainSubstring("test")))
Expect(captureStdout(func(w io.Writer) {
ctx.Error("foobar")
l.Error("foobar")
})).To(And(ContainSubstring("ERROR"), ContainSubstring("foobar")))
Expect(captureStdout(func(w io.Writer) {
ctx.Warning("foowarn")
l.Warning("foowarn")
})).To(And(ContainSubstring("WARNING"), ContainSubstring("foowarn")))
l, err := ioutil.ReadFile(t.Name())
ll, err := ioutil.ReadFile(t.Name())
Expect(err).ToNot(HaveOccurred())
logs := string(l)
logs := string(ll)
Expect(logs).To(ContainSubstring("foot"))
Expect(logs).To(ContainSubstring("test"))
Expect(logs).To(ContainSubstring("foowarn"))

View File

@@ -0,0 +1,43 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package logger
import (
"errors"
"os"
"github.com/mattn/go-isatty"
"golang.org/x/term"
)
func IsTerminal() bool {
return isatty.IsTerminal(os.Stdout.Fd())
}
// GetTerminalSize returns the width and the height of the active terminal.
func GetTerminalSize() (width, height int, err error) {
w, h, err := term.GetSize(int(os.Stdout.Fd()))
if w <= 0 {
w = 0
}
if h <= 0 {
h = 0
}
if err != nil {
err = errors.New("size not detectable")
}
return w, h, err
}

View File

@@ -0,0 +1,39 @@
// Copyright © 2022 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package template
import (
"os"
"path/filepath"
)
const Directory = "templates"
// FindPossibleTemplatesDir returns templates dir located at root
func FindPossibleTemplatesDir(root string) (res []string) {
var ff = func(currentpath string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if info.IsDir() && info.Name() == Directory {
res = append(res, currentpath)
}
return nil
}
filepath.Walk(root, ff)
return
}

View File

@@ -41,7 +41,7 @@ import (
bus "github.com/mudler/luet/pkg/api/core/bus"
config "github.com/mudler/luet/pkg/api/core/config"
"github.com/mudler/luet/pkg/api/core/image"
types "github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/types"
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"
@@ -70,7 +70,7 @@ type PackageArtifact struct {
Runtime *pkg.DefaultPackage `json:"runtime,omitempty"`
}
func ImageToArtifact(ctx *types.Context, img v1.Image, t compression.Implementation, output string, filter func(h *tar.Header) (bool, error)) (*PackageArtifact, error) {
func ImageToArtifact(ctx types.Context, img v1.Image, t compression.Implementation, output string, filter func(h *tar.Header) (bool, error)) (*PackageArtifact, error) {
_, tmpdiffs, err := image.Extract(ctx, img, filter)
if err != nil {
return nil, errors.Wrap(err, "Error met while creating tempdir for rootfs")
@@ -176,12 +176,12 @@ func (a *PackageArtifact) GetFileName() string {
}
// CreateArtifactForFile creates a new artifact from the given file
func CreateArtifactForFile(ctx *types.Context, 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 := ctx.Config.GetSystem().TempDir("archive")
archive, err := ctx.TempDir("archive")
if err != nil {
return nil, errors.Wrap(err, "error met while creating tempdir for "+s)
}
@@ -191,7 +191,7 @@ func CreateArtifactForFile(ctx *types.Context, s string, opts ...func(*PackageAr
return nil, errors.Wrapf(err, "error while copying %s to %s", s, dst)
}
artifact, err := ctx.Config.GetSystem().TempDir("artifact")
artifact, err := ctx.TempDir("artifact")
if err != nil {
return nil, errors.Wrap(err, "error met while creating tempdir for "+s)
}
@@ -210,9 +210,9 @@ type ImageBuilder interface {
}
// GenerateFinalImage takes an artifact and builds a Docker image with its content
func (a *PackageArtifact) GenerateFinalImage(ctx *types.Context, imageName string, b ImageBuilder, keepPerms bool) error {
func (a *PackageArtifact) GenerateFinalImage(ctx types.Context, imageName string, b ImageBuilder, keepPerms bool) error {
tempimage, err := ctx.Config.GetSystem().TempFile("tempimage")
tempimage, err := ctx.TempFile("tempimage")
if err != nil {
return errors.Wrap(err, "error met while creating tempdir for "+a.Path)
}
@@ -428,7 +428,7 @@ func replaceFileTarWrapper(dst string, inputTarStream io.ReadCloser, mods []stri
return pipeReader
}
func tarModifierWrapperFunc(ctx *types.Context) func(dst, path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error) {
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
@@ -495,10 +495,10 @@ func tarModifierWrapperFunc(ctx *types.Context) func(dst, path string, header *t
}
}
func (a *PackageArtifact) GetProtectFiles(ctx *types.Context) (res []string) {
func (a *PackageArtifact) GetProtectFiles(ctx types.Context) (res []string) {
annotationDir := ""
if !ctx.Config.ConfigProtectSkip {
if !ctx.GetConfig().ConfigProtectSkip {
// a.CompileSpec could be nil when artifact.Unpack is used for tree tarball
if a.CompileSpec != nil &&
@@ -511,7 +511,7 @@ func (a *PackageArtifact) GetProtectFiles(ctx *types.Context) (res []string) {
// TODO: check if skip this if we have a.CompileSpec nil
cp := config.NewConfigProtect(annotationDir)
cp.Map(a.Files, ctx.Config.GetConfigProtectConfFiles())
cp.Map(a.Files, ctx.GetConfig().ConfigProtectConfFiles)
// NOTE: for unpack we need files path without initial /
res = cp.GetProtectFiles(false)
@@ -521,7 +521,7 @@ func (a *PackageArtifact) GetProtectFiles(ctx *types.Context) (res []string) {
}
// Unpack Untar and decompress (TODO) to the given path
func (a *PackageArtifact) Unpack(ctx *types.Context, dst string, keepPerms bool) error {
func (a *PackageArtifact) Unpack(ctx types.Context, dst string, keepPerms bool) error {
if !strings.HasPrefix(dst, string(os.PathSeparator)) {
return errors.New("destination must be an absolute path")

View File

@@ -18,7 +18,7 @@ package artifact_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -20,10 +20,9 @@ import (
"os"
"path/filepath"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
. "github.com/mudler/luet/pkg/api/core/types/artifact"
. "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"
@@ -33,13 +32,13 @@ import (
fileHelper "github.com/mudler/luet/pkg/helpers/file"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/tree"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Artifact", func() {
Context("Simple package build definition", func() {
ctx := types.NewContext()
ctx := context.NewContext()
It("Generates a verified delta", func() {
generalRecipe := tree.NewGeneralRecipe(pkg.NewInMemoryDatabase(false))
@@ -49,7 +48,7 @@ var _ = Describe("Artifact", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(1))
cc := NewLuetCompiler(nil, generalRecipe.GetDatabase(), options.WithContext(types.NewContext()))
cc := NewLuetCompiler(nil, generalRecipe.GetDatabase(), options.WithContext(context.NewContext()))
lspec, err := cc.FromPackage(&pkg.DefaultPackage{Name: "enman", Category: "app-admin", Version: "1.4.0"})
Expect(err).ToNot(HaveOccurred())
@@ -83,7 +82,7 @@ WORKDIR /luetbuild
ENV PACKAGE_NAME=enman
ENV PACKAGE_VERSION=1.4.0
ENV PACKAGE_CATEGORY=app-admin`))
b := NewSimpleDockerBackend(ctx)
b := backend.NewSimpleDockerBackend(ctx)
opts := backend.Options{
ImageName: "luet/base",
SourcePath: tmpdir,
@@ -120,7 +119,7 @@ RUN echo bar > /test2`))
})
It("Generates packages images", func() {
b := NewSimpleDockerBackend(ctx)
b := backend.NewSimpleDockerBackend(ctx)
imageprefix := "foo/"
testString := []byte(`funky test data`)
@@ -177,7 +176,7 @@ RUN echo bar > /test2`))
})
It("Generates empty packages images", func() {
b := NewSimpleDockerBackend(ctx)
b := backend.NewSimpleDockerBackend(ctx)
imageprefix := "foo/"
tmpdir, err := ioutil.TempDir(os.TempDir(), "artifact")

View File

@@ -20,13 +20,13 @@ import (
"os"
"path/filepath"
types "github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
. "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"
pkg "github.com/mudler/luet/pkg/package"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -59,7 +59,7 @@ var _ = Describe("Cache", func() {
Expect(err).ToNot(HaveOccurred())
b := NewPackageArtifact(path)
ctx := types.NewContext()
ctx := context.NewContext()
err = b.Unpack(ctx, tmpdir, false)
Expect(err).ToNot(HaveOccurred())

View File

@@ -45,7 +45,7 @@ type HashOptions struct {
func (c Checksums) List() (res [][]string) {
keys := make([]string, 0)
for k, _ := range c {
for k := range c {
keys = append(keys, k)
}
sort.Strings(keys)

View File

@@ -21,7 +21,7 @@ import (
. "github.com/mudler/luet/pkg/api/core/types/artifact"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -1,6 +1,4 @@
// Copyright © 2019 Ettore Di Giacinto <mudler@gentoo.org>
// Daniele Rondina <geaaru@sabayonlinux.org>
// 2021 Ettore Di Giacinto <mudler@mocaccino.org>
// Copyright © 2019-2021 Ettore Di Giacinto <mudler@gentoo.org>
//
// 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
@@ -39,19 +37,22 @@ var AvailableResolvers = strings.Join([]string{solver.QLearningResolverType}, "
type LuetLoggingConfig struct {
// Path of the logfile
Path string `mapstructure:"path"`
Path string `yaml:"path" mapstructure:"path"`
// Enable/Disable logging to file
EnableLogFile bool `mapstructure:"enable_logfile"`
EnableLogFile bool `yaml:"enable_logfile" mapstructure:"enable_logfile"`
// Enable JSON format logging in file
JsonFormat bool `mapstructure:"json_format"`
JsonFormat bool `yaml:"json_format" mapstructure:"json_format"`
// Log level
Level LogLevel `mapstructure:"level"`
Level string `yaml:"level" mapstructure:"level"`
// Enable emoji
EnableEmoji bool `mapstructure:"enable_emoji"`
EnableEmoji bool `yaml:"enable_emoji" mapstructure:"enable_emoji"`
// Enable/Disable color in logging
Color bool `mapstructure:"color"`
Color bool `yaml:"color" mapstructure:"color"`
// NoSpinner disable spinner
NoSpinner bool `yaml:"no_spinner" mapstructure:"no_spinner"`
}
type LuetGeneralConfig struct {
@@ -108,8 +109,42 @@ type LuetSystemConfig struct {
TmpDirBase string `yaml:"tmpdir_base" mapstructure:"tmpdir_base"`
}
func (s *LuetSystemConfig) SetRootFS(path string) error {
p, err := fileHelper.Rel2Abs(path)
// Init reads the config and replace user-defined paths with
// absolute paths where necessary, and construct the paths for the cache
// and database on the real system
func (c *LuetConfig) Init() error {
if err := c.System.init(); err != nil {
return err
}
if err := c.loadConfigProtect(); err != nil {
return err
}
// Load repositories
if err := c.loadRepositories(); err != nil {
return err
}
return nil
}
func (s *LuetSystemConfig) init() error {
if err := s.setRootfs(); err != nil {
return err
}
if err := s.setDBPath(); err != nil {
return err
}
s.setCachePath()
return nil
}
func (s *LuetSystemConfig) setRootfs() error {
p, err := fileHelper.Rel2Abs(s.Rootfs)
if err != nil {
return err
}
@@ -118,9 +153,8 @@ func (s *LuetSystemConfig) SetRootFS(path string) error {
return nil
}
func (sc *LuetSystemConfig) GetRepoDatabaseDirPath(name string) string {
dbpath := filepath.Join(sc.Rootfs, sc.DatabasePath)
dbpath = filepath.Join(dbpath, "repos/"+name)
func (sc LuetSystemConfig) GetRepoDatabaseDirPath(name string) string {
dbpath := filepath.Join(sc.DatabasePath, "repos/"+name)
err := os.MkdirAll(dbpath, os.ModePerm)
if err != nil {
panic(err)
@@ -128,45 +162,48 @@ func (sc *LuetSystemConfig) GetRepoDatabaseDirPath(name string) string {
return dbpath
}
func (sc *LuetSystemConfig) GetSystemRepoDatabaseDirPath() string {
func (sc *LuetSystemConfig) setDBPath() error {
dbpath := filepath.Join(sc.Rootfs,
sc.DatabasePath)
err := os.MkdirAll(dbpath, os.ModePerm)
if err != nil {
panic(err)
return err
}
return dbpath
sc.DatabasePath = dbpath
return nil
}
func (sc *LuetSystemConfig) GetSystemPkgsCacheDirPath() (p string) {
func (sc *LuetSystemConfig) setCachePath() {
var cachepath string
if sc.PkgsCachePath != "" {
cachepath = sc.PkgsCachePath
if !filepath.IsAbs(cachepath) {
cachepath = filepath.Join(sc.DatabasePath, sc.PkgsCachePath)
os.MkdirAll(cachepath, os.ModePerm)
} else {
cachepath = sc.PkgsCachePath
}
} else {
// Create dynamic cache for test suites
cachepath, _ = ioutil.TempDir(os.TempDir(), "cachepkgs")
}
if filepath.IsAbs(cachepath) {
p = cachepath
} else {
p = filepath.Join(sc.GetSystemRepoDatabaseDirPath(), cachepath)
}
sc.PkgsCachePath = cachepath // Be consistent with the path we set
return
}
func (sc *LuetSystemConfig) GetRootFsAbs() (string, error) {
return filepath.Abs(sc.Rootfs)
}
type LuetKV struct {
type FinalizerEnv struct {
Key string `json:"key" yaml:"key" mapstructure:"key"`
Value string `json:"value" yaml:"value" mapstructure:"value"`
}
type Finalizers []FinalizerEnv
func (f Finalizers) Slice() (sl []string) {
for _, kv := range f {
sl = append(sl, fmt.Sprintf("%s=%s", kv.Key, kv.Value))
}
return
}
type LuetConfig struct {
Logging LuetLoggingConfig `yaml:"logging,omitempty" mapstructure:"logging"`
General LuetGeneralConfig `yaml:"general,omitempty" mapstructure:"general"`
@@ -179,16 +216,16 @@ type LuetConfig struct {
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"`
FinalizerEnvs Finalizers `json:"finalizer_envs,omitempty" yaml:"finalizer_envs,omitempty" mapstructure:"finalizer_envs,omitempty"`
ConfigProtectConfFiles []config.ConfigProtectConfFile `yaml:"-" mapstructure:"-"`
}
func (c *LuetConfig) GetSystemDB() pkg.PackageDatabase {
switch c.GetSystem().DatabaseEngine {
switch c.System.DatabaseEngine {
case "boltdb":
return pkg.NewBoltDatabase(
filepath.Join(c.GetSystem().GetSystemRepoDatabaseDirPath(), "luet.db"))
filepath.Join(c.System.DatabasePath, "luet.db"))
default:
return pkg.NewInMemoryDatabase(true)
}
@@ -198,83 +235,30 @@ func (c *LuetConfig) AddSystemRepository(r LuetRepository) {
c.SystemRepositories = append(c.SystemRepositories, r)
}
func (c *LuetConfig) GetFinalizerEnvsMap() map[string]string {
ans := make(map[string]string)
for _, kv := range c.FinalizerEnvs {
ans[kv.Key] = kv.Value
}
return ans
}
func (c *LuetConfig) SetFinalizerEnv(k, v string) {
keyPresent := false
envs := []LuetKV{}
envs := []FinalizerEnv{}
for _, kv := range c.FinalizerEnvs {
if kv.Key == k {
keyPresent = true
envs = append(envs, LuetKV{Key: kv.Key, Value: v})
envs = append(envs, FinalizerEnv{Key: kv.Key, Value: v})
} else {
envs = append(envs, kv)
}
}
if !keyPresent {
envs = append(envs, LuetKV{Key: k, Value: v})
envs = append(envs, FinalizerEnv{Key: k, Value: v})
}
c.FinalizerEnvs = envs
}
func (c *LuetConfig) GetFinalizerEnvs() []string {
ans := []string{}
for _, kv := range c.FinalizerEnvs {
ans = append(ans, fmt.Sprintf("%s=%s", kv.Key, kv.Value))
}
return ans
}
func (c *LuetConfig) GetFinalizerEnv(k string) (string, error) {
keyNotPresent := true
ans := ""
for _, kv := range c.FinalizerEnvs {
if kv.Key == k {
keyNotPresent = false
ans = kv.Value
}
}
if keyNotPresent {
return "", errors.New("Finalizer key " + k + " not found")
}
return ans, nil
}
func (c *LuetConfig) GetLogging() *LuetLoggingConfig {
return &c.Logging
}
func (c *LuetConfig) GetGeneral() *LuetGeneralConfig {
return &c.General
}
func (c *LuetConfig) GetSystem() *LuetSystemConfig {
return &c.System
}
func (c *LuetConfig) GetSolverOptions() *LuetSolverOptions {
return &c.Solver
}
func (c *LuetConfig) YAML() ([]byte, error) {
return yaml.Marshal(c)
}
func (c *LuetConfig) GetConfigProtectConfFiles() []config.ConfigProtectConfFile {
return c.ConfigProtectConfFiles
}
func (c *LuetConfig) AddConfigProtectConfFile(file *config.ConfigProtectConfFile) {
func (c *LuetConfig) addProtectFile(file *config.ConfigProtectConfFile) {
if c.ConfigProtectConfFiles == nil {
c.ConfigProtectConfFiles = []config.ConfigProtectConfFile{*file}
} else {
@@ -282,28 +266,21 @@ func (c *LuetConfig) AddConfigProtectConfFile(file *config.ConfigProtectConfFile
}
}
func (c *LuetConfig) LoadRepositories(ctx *Context) error {
func (c *LuetConfig) loadRepositories() 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
}
rootfs = c.System.Rootfs
}
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
}
@@ -313,27 +290,20 @@ func (c *LuetConfig) LoadRepositories(ctx *Context) error {
}
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
}
@@ -359,28 +329,20 @@ func (c *LuetConfig) GetSystemRepository(name string) (*LuetRepository, error) {
return ans, nil
}
func (c *LuetConfig) LoadConfigProtect(ctx *Context) error {
func (c *LuetConfig) loadConfigProtect() 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
}
rootfs = c.System.Rootfs
}
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
}
@@ -390,38 +352,31 @@ func (c *LuetConfig) LoadConfigProtect(ctx *Context) error {
}
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)
r, err := loadConfigProtectConfFile(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)
c.addProtectFile(r)
}
}
return nil
}
func loadConfigProtectConFile(filename string, data []byte) (*config.ConfigProtectConfFile, error) {
func loadConfigProtectConfFile(filename string, data []byte) (*config.ConfigProtectConfFile, error) {
ans := config.NewConfigProtectConfFile(filename)
err := yaml.Unmarshal(data, &ans)
if err != nil {
@@ -429,47 +384,3 @@ func loadConfigProtectConFile(filename string, data []byte) (*config.ConfigProte
}
return ans, nil
}
func (c *LuetLoggingConfig) SetLogLevel(s LogLevel) {
c.Level = s
}
func (c *LuetSystemConfig) InitTmpDir() error {
if !filepath.IsAbs(c.TmpDirBase) {
abs, err := fileHelper.Rel2Abs(c.TmpDirBase)
if err != nil {
return errors.Wrap(err, "while converting relative path to absolute path")
}
c.TmpDirBase = abs
}
if _, err := os.Stat(c.TmpDirBase); err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(c.TmpDirBase, os.ModePerm)
if err != nil {
return err
}
}
}
return nil
}
func (c *LuetSystemConfig) CleanupTmpDir() error {
return os.RemoveAll(c.TmpDirBase)
}
func (c *LuetSystemConfig) TempDir(pattern string) (string, error) {
err := c.InitTmpDir()
if err != nil {
return "", err
}
return ioutil.TempDir(c.TmpDirBase, pattern)
}
func (c *LuetSystemConfig) TempFile(pattern string) (*os.File, error) {
err := c.InitTmpDir()
if err != nil {
return nil, err
}
return ioutil.TempFile(c.TmpDirBase, pattern)
}

View File

@@ -18,7 +18,7 @@ package types_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -17,53 +17,86 @@
package types_test
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
types "github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/api/core/types"
fileHelper "github.com/mudler/luet/pkg/helpers/file"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "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)
Context("Inits paths", func() {
t, _ := ioutil.TempDir("", "tests")
defer os.RemoveAll(t)
c := &types.LuetConfig{
System: types.LuetSystemConfig{
Rootfs: t,
PkgsCachePath: "foo",
DatabasePath: "baz",
}}
It("sets default", func() {
err := c.Init()
Expect(err).ToNot(HaveOccurred())
Expect(c.System.Rootfs).To(Equal(t))
Expect(c.System.PkgsCachePath).To(Equal(filepath.Join(t, "baz", "foo")))
Expect(c.System.DatabasePath).To(Equal(filepath.Join(t, "baz")))
})
})
Context("Load Repository1", func() {
var ctx *context.Context
BeforeEach(func() {
ctx = context.NewContext(context.WithConfig(&types.LuetConfig{
RepositoriesConfDir: []string{
"../../../../tests/fixtures/repos.conf.d",
},
}))
ctx.Config.Init()
})
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"))
Expect(len(ctx.GetConfig().SystemRepositories)).Should(Equal(2))
Expect(ctx.GetConfig().SystemRepositories[0].Name).Should(Equal("test1"))
Expect(ctx.GetConfig().SystemRepositories[0].Priority).Should(Equal(999))
Expect(ctx.GetConfig().SystemRepositories[0].Type).Should(Equal("disk"))
Expect(len(ctx.GetConfig().SystemRepositories[0].Urls)).Should(Equal(1))
Expect(ctx.GetConfig().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"))
Expect(len(ctx.GetConfig().SystemRepositories)).Should(Equal(2))
Expect(ctx.GetConfig().SystemRepositories[1].Name).Should(Equal("test2"))
Expect(ctx.GetConfig().SystemRepositories[1].Priority).Should(Equal(1000))
Expect(ctx.GetConfig().SystemRepositories[1].Type).Should(Equal("disk"))
Expect(len(ctx.GetConfig().SystemRepositories[1].Urls)).Should(Equal(1))
Expect(ctx.GetConfig().SystemRepositories[1].Urls[0]).Should(Equal("tests/repos/test2"))
})
})
Context("Simple temporary directory creation", func() {
ctx := context.NewContext(context.WithConfig(&types.LuetConfig{
System: types.LuetSystemConfig{
TmpDirBase: os.TempDir() + "/tmpluet",
},
}))
BeforeEach(func() {
ctx = context.NewContext(context.WithConfig(&types.LuetConfig{
System: types.LuetSystemConfig{
TmpDirBase: os.TempDir() + "/tmpluet",
},
}))
})
It("Create Temporary directory", func() {
ctx := types.NewContext()
ctx.Config.GetSystem().TmpDirBase = os.TempDir() + "/tmpluet"
tmpDir, err := ctx.Config.GetSystem().TempDir("test1")
tmpDir, err := ctx.TempDir("test1")
Expect(err).ToNot(HaveOccurred())
Expect(strings.HasPrefix(tmpDir, filepath.Join(os.TempDir(), "tmpluet"))).To(BeTrue())
Expect(fileHelper.Exists(tmpDir)).To(BeTrue())
@@ -72,11 +105,7 @@ var _ = Describe("Config", func() {
})
It("Create Temporary file", func() {
ctx := types.NewContext()
ctx.Config.GetSystem().TmpDirBase = os.TempDir() + "/tmpluet"
tmpFile, err := ctx.Config.GetSystem().TempFile("testfile1")
tmpFile, err := ctx.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())

View File

@@ -15,417 +15,16 @@
package types
import (
"context"
"fmt"
"os"
"path"
"path/filepath"
"regexp"
"runtime"
"strings"
"sync"
type Context interface {
Logger
GarbageCollector
GetConfig() LuetConfig
Copy() Context
// SetAnnotation sets generic annotations to hold in a context
SetAnnotation(s string, i interface{})
"github.com/kyokomi/emoji"
"github.com/mudler/luet/pkg/helpers/terminal"
"github.com/pkg/errors"
"github.com/pterm/pterm"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/term"
)
// GetAnnotation gets generic annotations to hold in a context
GetAnnotation(s string) interface{}
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
name string
s *pterm.SpinnerPrinter
spinnerLock *sync.Mutex
z *zap.Logger
ProgressBar *pterm.ProgressbarPrinter
}
func NewContext() *Context {
return &Context{
spinnerLock: &sync.Mutex{},
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) WithName(name string) *Context {
newc := c.Copy()
newc.name = name
return newc
}
func (c *Context) Copy() *Context {
configCopy := *c.Config
configCopy.System = *c.Config.GetSystem()
configCopy.General = *c.Config.GetGeneral()
configCopy.Logging = *c.Config.GetLogging()
ctx := *c
ctxCopy := &ctx
ctxCopy.Config = &configCopy
return ctxCopy
}
// GetTerminalSize returns the width and the height of the active terminal.
func (c *Context) GetTerminalSize() (width, height int, err error) {
w, h, err := term.GetSize(int(os.Stdout.Fd()))
if w <= 0 {
w = 0
}
if h <= 0 {
h = 0
}
if err != nil {
err = errors.New("size not detectable")
}
return w, h, err
}
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()
}
if c.Config.General.Quiet {
c.NoColor()
pterm.DisableStyling()
}
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:
levelMsg = message
case 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.name != "" {
levelMsg = fmt.Sprintf("[%s] %s", c.name, 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)
}
WithLoggingContext(s string) Context
}

View File

@@ -0,0 +1,25 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package types
import "os"
type GarbageCollector interface {
Clean() error
TempDir(pattern string) (string, error)
TempFile(s string) (*os.File, error)
String() string
}

View File

@@ -0,0 +1,41 @@
// Copyright © 2021 Ettore Di Giacinto <mudler@mocaccino.org>
//
// 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 <http://www.gnu.org/licenses/>.
package types
// Logger is a standard logging interface
type Logger interface {
Info(...interface{})
Success(...interface{})
Warning(...interface{})
Warn(...interface{})
Debug(...interface{})
Error(...interface{})
Fatal(...interface{})
Panic(...interface{})
Trace(...interface{})
Infof(string, ...interface{})
Warnf(string, ...interface{})
Debugf(string, ...interface{})
Errorf(string, ...interface{})
Fatalf(string, ...interface{})
Panicf(string, ...interface{})
Tracef(string, ...interface{})
SpinnerStop()
Spinner()
Ask() bool
Screen(string)
}

View File

@@ -19,7 +19,7 @@ import (
"runtime"
types "github.com/mudler/luet/pkg/api/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -2,13 +2,13 @@ package compiler
import (
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/compiler/backend"
"github.com/pkg/errors"
)
func NewBackend(ctx *types.Context, s string) (CompilerBackend, error) {
func NewBackend(ctx types.Context, s string) (CompilerBackend, error) {
var compilerBackend CompilerBackend
switch s {

View File

@@ -18,7 +18,7 @@ package backend_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -19,8 +19,6 @@ import (
"os/exec"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/pkg/errors"
)
@@ -29,11 +27,6 @@ const (
DockerBackend = "docker"
)
func imageAvailable(image string) bool {
_, err := crane.Digest(image)
return err == nil
}
type Options struct {
ImageName string
SourcePath string
@@ -43,9 +36,9 @@ type Options struct {
BackendArgs []string
}
func runCommand(ctx *types.Context, cmd *exec.Cmd) error {
func runCommand(ctx types.Context, cmd *exec.Cmd) error {
output := ""
buffered := !ctx.Config.GetGeneral().ShowBuildOutput
buffered := !ctx.GetConfig().General.ShowBuildOutput
writer := NewBackendWriter(buffered, ctx)
cmd.Stdout = writer

View File

@@ -24,6 +24,7 @@ import (
"github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/google/go-containerregistry/pkg/v1/tarball"
bus "github.com/mudler/luet/pkg/api/core/bus"
"github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
v1 "github.com/google/go-containerregistry/pkg/v1"
@@ -32,10 +33,10 @@ import (
)
type SimpleDocker struct {
ctx *types.Context
ctx types.Context
}
func NewSimpleDockerBackend(ctx *types.Context) *SimpleDocker {
func NewSimpleDockerBackend(ctx types.Context) *SimpleDocker {
return &SimpleDocker{ctx: ctx}
}
@@ -118,7 +119,7 @@ func (s *SimpleDocker) ImageExists(imagename string) bool {
}
func (*SimpleDocker) ImageAvailable(imagename string) bool {
return imageAvailable(imagename)
return image.Available(imagename)
}
func (s *SimpleDocker) RemoveImage(opts Options) error {
@@ -190,7 +191,7 @@ func (s *SimpleDocker) imageFromCLIPipe(a string) (v1.Image, error) {
}
func (s *SimpleDocker) imageFromDisk(a string) (v1.Image, error) {
f, err := s.ctx.Config.GetSystem().TempFile("snapshot")
f, err := s.ctx.TempFile("snapshot")
if err != nil {
return nil, err
}

View File

@@ -16,7 +16,7 @@
package backend_test
import (
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
. "github.com/mudler/luet/pkg/compiler"
"github.com/mudler/luet/pkg/compiler/backend"
. "github.com/mudler/luet/pkg/compiler/backend"
@@ -28,13 +28,13 @@ import (
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/tree"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Docker backend", func() {
Context("Simple Docker backend satisfies main interface functionalities", func() {
ctx := types.NewContext()
ctx := context.NewContext()
It("Builds and generate tars", func() {
generalRecipe := tree.NewGeneralRecipe(pkg.NewInMemoryDatabase(false))

View File

@@ -22,16 +22,17 @@ import (
"github.com/google/go-containerregistry/pkg/crane"
v1 "github.com/google/go-containerregistry/pkg/v1"
bus "github.com/mudler/luet/pkg/api/core/bus"
"github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/pkg/errors"
)
type SimpleImg struct {
ctx *types.Context
ctx types.Context
}
func NewSimpleImgBackend(ctx *types.Context) *SimpleImg {
func NewSimpleImgBackend(ctx types.Context) *SimpleImg {
return &SimpleImg{ctx: ctx}
}
@@ -77,7 +78,7 @@ func (s *SimpleImg) RemoveImage(opts Options) error {
func (s *SimpleImg) ImageReference(a string, ondisk bool) (v1.Image, error) {
f, err := s.ctx.Config.GetSystem().TempFile("snapshot")
f, err := s.ctx.TempFile("snapshot")
if err != nil {
return nil, err
}
@@ -135,7 +136,7 @@ func (s *SimpleImg) CopyImage(src, dst string) error {
}
func (s *SimpleImg) ImageAvailable(imagename string) bool {
return imageAvailable(imagename)
return image.Available(imagename)
}
// ImageExists check if the given image is available locally

View File

@@ -25,10 +25,10 @@ import (
type BackendWriter struct {
BufferedOutput bool
Buffer *bytes.Buffer
ctx *types.Context
ctx types.Context
}
func NewBackendWriter(buffered bool, ctx *types.Context) *BackendWriter {
func NewBackendWriter(buffered bool, ctx types.Context) *BackendWriter {
return &BackendWriter{
BufferedOutput: buffered,
Buffer: &bytes.Buffer{},
@@ -41,7 +41,7 @@ func (b *BackendWriter) Write(p []byte) (int, error) {
return b.Buffer.Write(p)
}
b.ctx.Msg("info", false, (string(p)))
b.ctx.Info((string(p)))
return len(p), nil
}

View File

@@ -30,8 +30,8 @@ import (
"time"
bus "github.com/mudler/luet/pkg/api/core/bus"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/api/core/image"
"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/compiler/types/options"
@@ -82,7 +82,7 @@ func NewLuetCompiler(backend CompilerBackend, db pkg.PackageDatabase, compilerOp
c := NewCompiler(compilerOpts...)
if c.Options.Context == nil {
c.Options.Context = types.NewContext()
c.Options.Context = context.NewContext()
}
// c.Options.BackendType
c.Backend = backend
@@ -239,8 +239,10 @@ func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p *compi
return nil, err
}
ctx := cs.Options.Context.WithLoggingContext(fmt.Sprintf("extract %s", runnerOpts.ImageName))
_, rootfs, err := image.Extract(
cs.Options.Context,
ctx,
img,
image.ExtractFiles(
cs.Options.Context,
@@ -273,7 +275,7 @@ func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p *compi
func (cs *LuetCompiler) unpackDelta(concurrency int, keepPermissions bool, p *compilerspec.LuetCompilationSpec, builderOpts, runnerOpts backend.Options) (*artifact.PackageArtifact, error) {
rootfs, err := cs.Options.Context.Config.System.TempDir("rootfs")
rootfs, err := cs.Options.Context.TempDir("rootfs")
if err != nil {
return nil, errors.Wrap(err, "Could not create tempdir")
}
@@ -350,7 +352,7 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag
p.SetSeedImage(image) // In this case, we ignore the build deps as we suppose that the image has them - otherwise we recompose the tree with a solver,
// and we build all the images first.
buildDir, err := cs.Options.Context.Config.System.TempDir("build")
buildDir, err := cs.Options.Context.TempDir("build")
if err != nil {
return builderOpts, runnerOpts, err
}
@@ -458,7 +460,7 @@ func (cs *LuetCompiler) genArtifact(p *compilerspec.LuetCompilationSpec, builder
if p.EmptyPackage() {
fakePackage := p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar")
rootfs, err = cs.Options.Context.Config.System.TempDir("rootfs")
rootfs, err = cs.Options.Context.TempDir("rootfs")
if err != nil {
return nil, errors.Wrap(err, "Could not create tempdir")
}
@@ -500,12 +502,14 @@ func (cs *LuetCompiler) genArtifact(p *compilerspec.LuetCompilationSpec, builder
}
}
filelist, err := a.FileList()
if err != nil {
return a, errors.Wrapf(err, "Failed getting package list for '%s' '%s'", a.Path, a.CompileSpec.Package.HumanReadableString())
if !p.Package.Hidden {
filelist, err := a.FileList()
if err != nil {
return a, errors.Wrapf(err, "Failed getting package list for '%s' '%s'", a.Path, a.CompileSpec.Package.HumanReadableString())
}
a.Files = filelist
}
a.Files = filelist
a.CompileSpec.GetPackage().SetBuildTimestamp(time.Now().String())
err = a.WriteYAML(p.GetOutputPath())
@@ -939,7 +943,7 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool
}
// otherwise, generate it and push it aside
joinDir, err := cs.Options.Context.Config.System.TempDir("join")
joinDir, err := cs.Options.Context.TempDir("join")
if err != nil {
return errors.Wrap(err, "could not create tempdir for joining images")
}
@@ -978,7 +982,7 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool
}
}
artifactDir, err := cs.Options.Context.Config.System.TempDir("join")
artifactDir, err := cs.Options.Context.TempDir("join")
if err != nil {
return errors.Wrap(err, "could not create tempdir for final artifact")
}
@@ -1341,7 +1345,7 @@ func (cs *LuetCompiler) templatePackage(vals []map[string]interface{}, pack pkg.
} else {
bv := cs.Options.BuildValuesFile
if len(vals) > 0 {
valuesdir, err := cs.Options.Context.Config.System.TempDir("genvalues")
valuesdir, err := cs.Options.Context.TempDir("genvalues")
if err != nil {
return nil, errors.Wrap(err, "Could not create tempdir")
}

View File

@@ -18,7 +18,7 @@ package compiler_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -24,8 +24,8 @@ import (
helpers "github.com/mudler/luet/tests/helpers"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/types/artifact"
. "github.com/mudler/luet/pkg/compiler"
sd "github.com/mudler/luet/pkg/compiler/backend"
@@ -35,12 +35,12 @@ import (
fileHelper "github.com/mudler/luet/pkg/helpers/file"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/tree"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Compiler", func() {
ctx := types.NewContext()
ctx := context.NewContext()
Context("Simple package build definition", func() {
It("Compiles it correctly", func() {
@@ -51,7 +51,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
@@ -94,7 +94,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.2"})
Expect(err).ToNot(HaveOccurred())
@@ -124,7 +124,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.2"})
Expect(err).ToNot(HaveOccurred())
@@ -156,7 +156,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(1), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(1), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
@@ -190,7 +190,7 @@ var _ = Describe("Compiler", func() {
err = generalRecipe.Load("../../tests/fixtures/templates")
Expect(err).ToNot(HaveOccurred())
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(context.NewContext()))
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(1))
pkg, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"})
@@ -214,7 +214,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(4))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
@@ -270,7 +270,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(1), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(1), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "extra", Category: "layer", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
@@ -794,7 +794,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.0"})
Expect(err).ToNot(HaveOccurred())
@@ -983,7 +983,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "runtime", Category: "layer", Version: "0.1"})
Expect(err).ToNot(HaveOccurred())
@@ -1018,7 +1018,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(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(context.NewContext()))
specs, err := compiler.FromDatabase(generalRecipe.GetDatabase(), true, "")
Expect(err).ToNot(HaveOccurred())
@@ -1037,7 +1037,7 @@ var _ = Describe("Compiler", func() {
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext()))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "runtime", Category: "layer", Version: "0.1"})
Expect(err).ToNot(HaveOccurred())
@@ -1064,5 +1064,41 @@ var _ = Describe("Compiler", func() {
files := art.Files
Expect(files).To(ContainElement("bin/busybox"))
})
It("is not generated after the compilation process and annotated in the metadata if a package is hidden", func() {
generalRecipe := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false))
err := generalRecipe.Load("../../tests/fixtures/packagelayers_hidden")
Expect(err).ToNot(HaveOccurred())
Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(context.NewContext()))
spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "runtime", Category: "layer", Version: "0.1"})
Expect(err).ToNot(HaveOccurred())
compiler.Options.CompressionType = compression.GZip
Expect(spec.GetPackage().GetPath()).ToNot(Equal(""))
tmpdir, err := ioutil.TempDir("", "tree")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(tmpdir) // clean up
spec.SetOutputPath(tmpdir)
artifacts, errs := compiler.CompileParallel(false, compilerspec.NewLuetCompilationspecs(spec))
Expect(errs).To(BeNil())
Expect(len(artifacts)).To(Equal(1))
Expect(len(artifacts[0].Dependencies)).To(Equal(1))
Expect(artifacts[0].Files).ToNot(ContainElement("bin/busybox"))
Expect(fileHelper.Exists(spec.Rel("runtime-layer-0.1.metadata.yaml"))).To(BeTrue())
art, err := LoadArtifactFromYaml(spec)
Expect(err).ToNot(HaveOccurred())
files := art.Files
Expect(files).ToNot(ContainElement("bin/busybox"))
})
})
})

View File

@@ -16,18 +16,18 @@
package compiler_test
import (
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
. "github.com/mudler/luet/pkg/compiler"
sd "github.com/mudler/luet/pkg/compiler/backend"
"github.com/mudler/luet/pkg/compiler/types/options"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/tree"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("ImageHashTree", func() {
ctx := types.NewContext()
ctx := context.NewContext()
generalRecipe := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false))
compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2))
hashtree := NewHashTree(generalRecipe.GetDatabase())

View File

@@ -53,7 +53,7 @@ type Compiler struct {
// Image repository to push to
PushFinalImagesRepository string
Context *types.Context
Context types.Context
}
func NewDefaultCompiler() *Compiler {
@@ -237,7 +237,7 @@ func WithSolverOptions(c types.LuetSolverOptions) func(cfg *Compiler) error {
}
}
func WithContext(c *types.Context) func(cfg *Compiler) error {
func WithContext(c types.Context) func(cfg *Compiler) error {
return func(cfg *Compiler) error {
cfg.Context = c
return nil

View File

@@ -18,7 +18,7 @@ package compilerspec_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -27,7 +27,7 @@ import (
. "github.com/mudler/luet/pkg/compiler"
pkg "github.com/mudler/luet/pkg/package"
"github.com/mudler/luet/pkg/tree"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -33,6 +33,7 @@ import (
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/daemon"
"github.com/mudler/luet/pkg/api/core/bus"
"github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go/v1"
@@ -127,7 +128,7 @@ type UnpackEventData struct {
}
// DownloadAndExtractDockerImage extracts a container image natively. It supports privileged/unprivileged mode
func DownloadAndExtractDockerImage(ctx *luettypes.Context, image, dest string, auth *types.AuthConfig, verify bool) (*images.Image, error) {
func DownloadAndExtractDockerImage(ctx luettypes.Context, image, dest string, auth *types.AuthConfig, verify bool) (*images.Image, error) {
if verify {
img, err := verifyImage(image, auth)
if err != nil {
@@ -192,3 +193,60 @@ func DownloadAndExtractDockerImage(ctx *luettypes.Context, image, dest string, a
},
}, nil
}
func ExtractDockerImage(ctx luettypes.Context, local, dest string)(*images.Image, error) {
if !fileHelper.Exists(dest) {
if err := os.MkdirAll(dest, os.ModePerm); err != nil {
return nil, errors.Wrapf(err, "cannot create destination directory")
}
}
ref, err := name.ParseReference(local)
if err != nil {
return nil, err
}
img, err := daemon.Image(ref)
if err != nil {
return nil, err
}
m, err := img.Manifest()
if err != nil {
return nil, err
}
mt, err := img.MediaType()
if err != nil {
return nil, err
}
d, err := img.Digest()
if err != nil {
return nil, err
}
var c int64
c, _, err = luetimages.ExtractTo(
ctx,
img,
dest,
nil,
)
if err != nil {
return nil, err
}
bus.Manager.Publish(bus.EventImagePostUnPack, UnpackEventData{Image: local, Dest: dest})
return &images.Image{
Name: local,
Labels: m.Annotations,
Target: specs.Descriptor{
MediaType: string(mt),
Digest: digest.Digest(d.String()),
Size: c,
},
}, nil
}

View File

@@ -22,7 +22,7 @@ import (
fileHelper "github.com/mudler/luet/pkg/helpers/file"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -21,7 +21,7 @@ import (
"path/filepath"
. "github.com/mudler/luet/pkg/helpers"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -18,7 +18,7 @@ package helpers_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -18,7 +18,7 @@ package helpers_test
import (
. "github.com/mudler/luet/pkg/helpers"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -1,12 +0,0 @@
// +build darwin dragonfly freebsd netbsd openbsd
package terminal
import "golang.org/x/sys/unix"
const ioctlReadTermios = unix.TIOCGETA
func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
return err == nil
}

View File

@@ -1,17 +0,0 @@
// +build !windows,!nacl,!plan9
package terminal
import (
"io"
"os"
)
func IsTerminal(w io.Writer) bool {
switch v := w.(type) {
case *os.File:
return isTerminal(int(v.Fd()))
default:
return false
}
}

View File

@@ -1,11 +0,0 @@
// +build js nacl plan9
package terminal
import (
"io"
)
func IsTerminal(w io.Writer) bool {
return false
}

View File

@@ -1,11 +0,0 @@
package terminal
import (
"golang.org/x/sys/unix"
)
// IsTerminal returns true if the given file descriptor is a terminal.
func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
return err == nil
}

View File

@@ -1,12 +0,0 @@
// +build linux aix zos
package terminal
import "golang.org/x/sys/unix"
const ioctlReadTermios = unix.TCGETS
func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
return err == nil
}

View File

@@ -1,27 +0,0 @@
// +build windows
package terminal
import (
"io"
"os"
"golang.org/x/sys/windows"
)
func IsTerminal(w io.Writer) bool {
switch v := w.(type) {
case *os.File:
handle := windows.Handle(v.Fd())
var mode uint32
if err := windows.GetConsoleMode(handle, &mode); err != nil {
return false
}
mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
if err := windows.SetConsoleMode(handle, mode); err != nil {
return false
}
return true
}
return false
}

View File

@@ -88,7 +88,7 @@ func printMatches(artefacts map[string]ArtifactMatch) {
for _, m := range artefacts {
d = append(d, []string{
fmt.Sprintf("%s/%s", m.Package.GetCategory(), m.Package.GetName()),
pterm.LightGreen(m.Package.GetVersion()), m.Package.GetLicense(), m.Repository.Name})
pterm.LightGreen(m.Package.GetVersion()), m.Package.GetLicense(), m.Repository.GetName()})
}
pterm.DefaultTable.WithHasHeader().WithData(d).Render()
fmt.Println()

View File

@@ -18,7 +18,7 @@ package client_test
import (
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

View File

@@ -24,9 +24,9 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/go-units"
luettypes "github.com/mudler/luet/pkg/api/core/types"
"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/helpers"
@@ -42,17 +42,17 @@ type DockerClient struct {
RepoData RepoData
auth *types.AuthConfig
Cache *artifact.ArtifactCache
context *luetTypes.Context
context luettypes.Context
}
func NewDockerClient(r RepoData, ctx *luetTypes.Context) *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(ctx.Config.GetSystem().GetSystemPkgsCacheDirPath()),
Cache: artifact.NewCache(ctx.GetConfig().System.PkgsCachePath),
context: ctx,
}
}
@@ -81,13 +81,13 @@ func (c *DockerClient) DownloadArtifact(a *artifact.PackageArtifact) (*artifact.
// We discard checksum, that are checked while during pull and unpack by containerd
resultingArtifact.Checksums = artifact.Checksums{}
temp, err := c.context.Config.GetSystem().TempDir("image")
temp, err := c.context.TempDir("image")
if err != nil {
return nil, err
}
defer os.RemoveAll(temp)
tempArtifact, err := c.context.Config.GetSystem().TempFile("artifact")
tempArtifact, err := c.context.TempFile("artifact")
if err != nil {
return nil, err
}
@@ -144,13 +144,13 @@ func (c *DockerClient) DownloadFile(name string) (string, error) {
// Files should be in URI/repository:<file>
ok := false
temp, err = c.context.Config.GetSystem().TempDir("tree")
temp, err = c.context.TempDir("tree")
if err != nil {
return "", err
}
for _, uri := range c.RepoData.Urls {
file, err = c.context.Config.GetSystem().TempFile("DockerClient")
file, err = c.context.TempFile("DockerClient")
if err != nil {
continue
}

View File

@@ -20,7 +20,7 @@ import (
"os"
"path/filepath"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
"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"
@@ -28,7 +28,7 @@ import (
pkg "github.com/mudler/luet/pkg/package"
. "github.com/mudler/luet/pkg/installer/client"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
@@ -38,7 +38,7 @@ import (
// mount/unmount layers.
var _ = Describe("Docker client", func() {
Context("With repository", func() {
ctx := types.NewContext()
ctx := context.NewContext()
repoImage := os.Getenv("UNIT_TEST_DOCKER_IMAGE")
var repoURL []string

View File

@@ -36,13 +36,13 @@ import (
type HttpClient struct {
RepoData RepoData
Cache *artifact.ArtifactCache
context *types.Context
context types.Context
}
func NewHttpClient(r RepoData, ctx *types.Context) *HttpClient {
func NewHttpClient(r RepoData, ctx types.Context) *HttpClient {
return &HttpClient{
RepoData: r,
Cache: artifact.NewCache(ctx.Config.GetSystem().GetSystemPkgsCacheDirPath()),
Cache: artifact.NewCache(ctx.GetConfig().System.PkgsCachePath),
context: ctx,
}
}
@@ -85,16 +85,16 @@ func Round(input float64) float64 {
func (c *HttpClient) DownloadFile(p string) (string, error) {
var file *os.File = nil
var downloaded bool
temp, err := c.context.Config.GetSystem().TempDir("download")
temp, err := c.context.TempDir("download")
if err != nil {
return "", err
}
defer os.RemoveAll(temp)
client := NewGrabClient(c.context.Config.General.HTTPTimeout)
client := NewGrabClient(c.context.GetConfig().General.HTTPTimeout)
for _, uri := range c.RepoData.Urls {
file, err = c.context.Config.GetSystem().TempFile("HttpClient")
file, err = c.context.TempFile("HttpClient")
if err != nil {
c.context.Debug("Failed downloading", p, "from", uri)
@@ -117,9 +117,12 @@ func (c *HttpClient) DownloadFile(p string) (string, error) {
// Initialize a progressbar only if we have one in the current context
var pb *pterm.ProgressbarPrinter
if c.context.ProgressBar != nil {
pb, _ = c.context.ProgressBar.WithTotal(int(resp.Size())).WithTitle(filepath.Base(resp.Request.HTTPRequest.URL.RequestURI())).Start()
pbb := c.context.GetAnnotation("progressbar")
switch v := pbb.(type) {
case *pterm.ProgressbarPrinter:
pb, _ = v.WithTotal(int(resp.Size())).WithTitle(filepath.Base(resp.Request.HTTPRequest.URL.RequestURI())).Start()
}
// start download loop
t := time.NewTicker(500 * time.Millisecond)
defer t.Stop()

View File

@@ -22,17 +22,17 @@ import (
"os"
"path/filepath"
"github.com/mudler/luet/pkg/api/core/types"
"github.com/mudler/luet/pkg/api/core/context"
"github.com/mudler/luet/pkg/api/core/types/artifact"
fileHelper "github.com/mudler/luet/pkg/helpers/file"
. "github.com/mudler/luet/pkg/installer/client"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("Http client", func() {
Context("With repository", func() {
ctx := types.NewContext()
ctx := context.NewContext()
It("Downloads single files", func() {
// setup small staticfile webserver with content

View File

@@ -29,12 +29,12 @@ import (
type LocalClient struct {
RepoData RepoData
Cache *artifact.ArtifactCache
context *types.Context
context types.Context
}
func NewLocalClient(r RepoData, ctx *types.Context) *LocalClient {
func NewLocalClient(r RepoData, ctx types.Context) *LocalClient {
return &LocalClient{
Cache: artifact.NewCache(ctx.Config.GetSystem().GetSystemPkgsCacheDirPath()),
Cache: artifact.NewCache(ctx.GetConfig().System.PkgsCachePath),
RepoData: r,
context: ctx,
}
@@ -78,11 +78,8 @@ func (c *LocalClient) DownloadFile(name string) (string, error) {
rootfs := ""
if !c.context.Config.ConfigFromHost {
rootfs, err = c.context.Config.GetSystem().GetRootFsAbs()
if err != nil {
return "", err
}
if !c.context.GetConfig().ConfigFromHost {
rootfs = c.context.GetConfig().System.Rootfs
}
ok := false
@@ -91,7 +88,7 @@ func (c *LocalClient) DownloadFile(name string) (string, error) {
uri = filepath.Join(rootfs, uri)
c.context.Info("Copying file", name, "from", uri)
file, err = c.context.Config.GetSystem().TempFile("localclient")
file, err = c.context.TempFile("localclient")
if err != nil {
continue
}

Some files were not shown because too many files have changed in this diff Show More