mirror of
https://github.com/mudler/luet.git
synced 2025-09-01 15:18:28 +00:00
Define context for scoped operation across core types
It holds necessary state plus additional information relative to the context which we are being run to (e.g. if we are in a terminal or not). Besides in the future we can use it also as a contextual logger to provide more smart logging capabilities. This also replace the general global configuration instance that previously was share between the core components.
This commit is contained in:
@@ -18,14 +18,11 @@ package backend_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/mudler/luet/cmd/util"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestSolver(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
LoadConfig()
|
||||
RunSpecs(t, "Backend Suite")
|
||||
}
|
||||
|
@@ -18,8 +18,7 @@ package backend
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/mudler/luet/pkg/config"
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
"github.com/mudler/luet/pkg/api/core/types"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/crane"
|
||||
"github.com/pkg/errors"
|
||||
@@ -44,17 +43,17 @@ type Options struct {
|
||||
BackendArgs []string
|
||||
}
|
||||
|
||||
func runCommand(cmd *exec.Cmd) error {
|
||||
func runCommand(ctx *types.Context, cmd *exec.Cmd) error {
|
||||
output := ""
|
||||
buffered := !config.LuetCfg.GetGeneral().ShowBuildOutput
|
||||
writer := NewBackendWriter(buffered)
|
||||
buffered := !ctx.Config.GetGeneral().ShowBuildOutput
|
||||
writer := NewBackendWriter(buffered, ctx)
|
||||
|
||||
cmd.Stdout = writer
|
||||
cmd.Stderr = writer
|
||||
|
||||
if buffered {
|
||||
Spinner(32)
|
||||
defer SpinnerStop()
|
||||
ctx.Spinner()
|
||||
defer ctx.SpinnerStop()
|
||||
}
|
||||
|
||||
err := cmd.Start()
|
||||
|
@@ -23,64 +23,66 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/mudler/luet/pkg/api/core/types"
|
||||
bus "github.com/mudler/luet/pkg/bus"
|
||||
fileHelper "github.com/mudler/luet/pkg/helpers/file"
|
||||
|
||||
capi "github.com/mudler/docker-companion/api"
|
||||
|
||||
"github.com/mudler/luet/pkg/helpers"
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type SimpleDocker struct{}
|
||||
type SimpleDocker struct {
|
||||
ctx *types.Context
|
||||
}
|
||||
|
||||
func NewSimpleDockerBackend() *SimpleDocker {
|
||||
return &SimpleDocker{}
|
||||
func NewSimpleDockerBackend(ctx *types.Context) *SimpleDocker {
|
||||
return &SimpleDocker{ctx: ctx}
|
||||
}
|
||||
|
||||
// TODO: Missing still: labels, and build args expansion
|
||||
func (*SimpleDocker) BuildImage(opts Options) error {
|
||||
func (s *SimpleDocker) BuildImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
bus.Manager.Publish(bus.EventImagePreBuild, opts)
|
||||
|
||||
buildarg := genBuildCommand(opts)
|
||||
Info(":whale2: Building image " + name)
|
||||
s.ctx.Info(":whale2: Building image " + name)
|
||||
cmd := exec.Command("docker", buildarg...)
|
||||
cmd.Dir = opts.SourcePath
|
||||
err := runCommand(cmd)
|
||||
err := runCommand(s.ctx, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Info(":whale: Building image " + name + " done")
|
||||
s.ctx.Info(":whale: Building image " + name + " done")
|
||||
|
||||
bus.Manager.Publish(bus.EventImagePostBuild, opts)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleDocker) CopyImage(src, dst string) error {
|
||||
Debug(":whale: Tagging image:", src, "->", dst)
|
||||
func (s *SimpleDocker) CopyImage(src, dst string) error {
|
||||
s.ctx.Debug(":whale: Tagging image:", src, "->", dst)
|
||||
cmd := exec.Command("docker", "tag", src, dst)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed tagging image: "+string(out))
|
||||
}
|
||||
Info(":whale: Tagged image:", src, "->", dst)
|
||||
s.ctx.Info(":whale: Tagged image:", src, "->", dst)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleDocker) DownloadImage(opts Options) error {
|
||||
func (s *SimpleDocker) DownloadImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
bus.Manager.Publish(bus.EventImagePrePull, opts)
|
||||
|
||||
buildarg := []string{"pull", name}
|
||||
Debug(":whale: Downloading image " + name)
|
||||
s.ctx.Debug(":whale: Downloading image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
|
||||
cmd := exec.Command("docker", buildarg...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
@@ -88,20 +90,20 @@ func (*SimpleDocker) DownloadImage(opts Options) error {
|
||||
return errors.Wrap(err, "Failed pulling image: "+string(out))
|
||||
}
|
||||
|
||||
Info(":whale: Downloaded image:", name)
|
||||
s.ctx.Info(":whale: Downloaded image:", name)
|
||||
bus.Manager.Publish(bus.EventImagePostPull, opts)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleDocker) ImageExists(imagename string) bool {
|
||||
func (s *SimpleDocker) ImageExists(imagename string) bool {
|
||||
buildarg := []string{"inspect", "--type=image", imagename}
|
||||
Debug(":whale: Checking existance of docker image: " + imagename)
|
||||
s.ctx.Debug(":whale: Checking existance of docker image: " + imagename)
|
||||
cmd := exec.Command("docker", buildarg...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
Debug("Image not present")
|
||||
Debug(string(out))
|
||||
s.ctx.Debug("Image not present")
|
||||
s.ctx.Debug(string(out))
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -111,31 +113,31 @@ func (*SimpleDocker) ImageAvailable(imagename string) bool {
|
||||
return imageAvailable(imagename)
|
||||
}
|
||||
|
||||
func (*SimpleDocker) RemoveImage(opts Options) error {
|
||||
func (s *SimpleDocker) RemoveImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
buildarg := []string{"rmi", name}
|
||||
out, err := exec.Command("docker", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed removing image: "+string(out))
|
||||
}
|
||||
Info(":whale: Removed image:", name)
|
||||
s.ctx.Info(":whale: Removed image:", name)
|
||||
//Info(string(out))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleDocker) Push(opts Options) error {
|
||||
func (s *SimpleDocker) Push(opts Options) error {
|
||||
name := opts.ImageName
|
||||
pusharg := []string{"push", name}
|
||||
bus.Manager.Publish(bus.EventImagePrePush, opts)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
|
||||
out, err := exec.Command("docker", pusharg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed pushing image: "+string(out))
|
||||
}
|
||||
Info(":whale: Pushed image:", name)
|
||||
s.ctx.Info(":whale: Pushed image:", name)
|
||||
bus.Manager.Publish(bus.EventImagePostPush, opts)
|
||||
|
||||
//Info(string(out))
|
||||
@@ -155,22 +157,22 @@ func (s *SimpleDocker) ImageDefinitionToTar(opts Options) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleDocker) ExportImage(opts Options) error {
|
||||
func (s *SimpleDocker) ExportImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
path := opts.Destination
|
||||
|
||||
buildarg := []string{"save", name, "-o", path}
|
||||
Debug(":whale: Saving image " + name)
|
||||
s.ctx.Debug(":whale: Saving image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
|
||||
out, err := exec.Command("docker", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed exporting image: "+string(out))
|
||||
}
|
||||
|
||||
Debug(":whale: Exported image:", name)
|
||||
s.ctx.Debug(":whale: Exported image:", name)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -196,15 +198,13 @@ func (b *SimpleDocker) ExtractRootfs(opts Options, keepPerms bool) error {
|
||||
|
||||
imageExport := filepath.Join(tempexport, "image.tar")
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
b.ctx.Spinner()
|
||||
defer b.ctx.SpinnerStop()
|
||||
|
||||
if err := b.ExportImage(Options{ImageName: name, Destination: imageExport}); err != nil {
|
||||
return errors.Wrap(err, "failed while extracting rootfs for "+name)
|
||||
}
|
||||
|
||||
SpinnerStop()
|
||||
|
||||
src := imageExport
|
||||
|
||||
if src == "" && opts.ImageName != "" {
|
||||
|
@@ -16,6 +16,7 @@
|
||||
package backend_test
|
||||
|
||||
import (
|
||||
"github.com/mudler/luet/pkg/api/core/types"
|
||||
"github.com/mudler/luet/pkg/api/core/types/artifact"
|
||||
"github.com/mudler/luet/pkg/compiler"
|
||||
. "github.com/mudler/luet/pkg/compiler"
|
||||
@@ -35,6 +36,7 @@ import (
|
||||
|
||||
var _ = Describe("Docker backend", func() {
|
||||
Context("Simple Docker backend satisfies main interface functionalities", func() {
|
||||
ctx := types.NewContext()
|
||||
It("Builds and generate tars", func() {
|
||||
generalRecipe := tree.NewGeneralRecipe(pkg.NewInMemoryDatabase(false))
|
||||
|
||||
@@ -69,7 +71,7 @@ WORKDIR /luetbuild
|
||||
ENV PACKAGE_NAME=enman
|
||||
ENV PACKAGE_VERSION=1.4.0
|
||||
ENV PACKAGE_CATEGORY=app-admin`))
|
||||
b := NewSimpleDockerBackend()
|
||||
b := NewSimpleDockerBackend(ctx)
|
||||
opts := backend.Options{
|
||||
ImageName: "luet/base",
|
||||
SourcePath: tmpdir,
|
||||
@@ -115,7 +117,7 @@ RUN echo bar > /test2`))
|
||||
artifacts = append(artifacts, artifact.ArtifactNode{Name: "/test", Size: 4})
|
||||
artifacts = append(artifacts, artifact.ArtifactNode{Name: "/test2", Size: 4})
|
||||
|
||||
Expect(compiler.GenerateChanges(b, opts, opts2)).To(Equal(
|
||||
Expect(compiler.GenerateChanges(ctx, b, opts, opts2)).To(Equal(
|
||||
[]artifact.ArtifactLayer{{
|
||||
FromImage: "luet/base",
|
||||
ToImage: "test",
|
||||
@@ -137,7 +139,7 @@ RUN echo bar > /test2`))
|
||||
})
|
||||
|
||||
It("Detects available images", func() {
|
||||
b := NewSimpleDockerBackend()
|
||||
b := NewSimpleDockerBackend(ctx)
|
||||
Expect(b.ImageAvailable("quay.io/mocaccino/extra")).To(BeTrue())
|
||||
Expect(b.ImageAvailable("ubuntu:20.10")).To(BeTrue())
|
||||
Expect(b.ImageAvailable("igjo5ijgo25nho52")).To(BeFalse())
|
||||
|
@@ -20,64 +20,65 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/mudler/luet/pkg/api/core/types"
|
||||
bus "github.com/mudler/luet/pkg/bus"
|
||||
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type SimpleImg struct{}
|
||||
type SimpleImg struct {
|
||||
ctx *types.Context
|
||||
}
|
||||
|
||||
func NewSimpleImgBackend() *SimpleImg {
|
||||
return &SimpleImg{}
|
||||
func NewSimpleImgBackend(ctx *types.Context) *SimpleImg {
|
||||
return &SimpleImg{ctx: ctx}
|
||||
}
|
||||
|
||||
// TODO: Missing still: labels, and build args expansion
|
||||
func (*SimpleImg) BuildImage(opts Options) error {
|
||||
func (s *SimpleImg) BuildImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
bus.Manager.Publish(bus.EventImagePreBuild, opts)
|
||||
|
||||
buildarg := genBuildCommand(opts)
|
||||
|
||||
Info(":tea: Building image " + name)
|
||||
s.ctx.Info(":tea: Building image " + name)
|
||||
|
||||
cmd := exec.Command("img", buildarg...)
|
||||
cmd.Dir = opts.SourcePath
|
||||
err := runCommand(cmd)
|
||||
err := runCommand(s.ctx, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bus.Manager.Publish(bus.EventImagePostBuild, opts)
|
||||
|
||||
Info(":tea: Building image " + name + " done")
|
||||
s.ctx.Info(":tea: Building image " + name + " done")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleImg) RemoveImage(opts Options) error {
|
||||
func (s *SimpleImg) RemoveImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
buildarg := []string{"rm", name}
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
out, err := exec.Command("img", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed removing image: "+string(out))
|
||||
}
|
||||
|
||||
Info(":tea: Image " + name + " removed")
|
||||
s.ctx.Info(":tea: Image " + name + " removed")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleImg) DownloadImage(opts Options) error {
|
||||
func (s *SimpleImg) DownloadImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
bus.Manager.Publish(bus.EventImagePrePull, opts)
|
||||
|
||||
buildarg := []string{"pull", name}
|
||||
Debug(":tea: Downloading image " + name)
|
||||
s.ctx.Debug(":tea: Downloading image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
|
||||
cmd := exec.Command("img", buildarg...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
@@ -85,27 +86,27 @@ func (*SimpleImg) DownloadImage(opts Options) error {
|
||||
return errors.Wrap(err, "Failed downloading image: "+string(out))
|
||||
}
|
||||
|
||||
Info(":tea: Image " + name + " downloaded")
|
||||
s.ctx.Info(":tea: Image " + name + " downloaded")
|
||||
bus.Manager.Publish(bus.EventImagePostPull, opts)
|
||||
|
||||
return nil
|
||||
}
|
||||
func (*SimpleImg) CopyImage(src, dst string) error {
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
func (s *SimpleImg) CopyImage(src, dst string) error {
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
|
||||
Debug(":tea: Tagging image", src, dst)
|
||||
s.ctx.Debug(":tea: Tagging image", src, dst)
|
||||
cmd := exec.Command("img", "tag", src, dst)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed tagging image: "+string(out))
|
||||
}
|
||||
Info(":tea: Image " + dst + " tagged")
|
||||
s.ctx.Info(":tea: Image " + dst + " tagged")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleImg) ImageAvailable(imagename string) bool {
|
||||
func (s *SimpleImg) ImageAvailable(imagename string) bool {
|
||||
return imageAvailable(imagename)
|
||||
}
|
||||
|
||||
@@ -135,20 +136,20 @@ func (s *SimpleImg) ImageDefinitionToTar(opts Options) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleImg) ExportImage(opts Options) error {
|
||||
func (s *SimpleImg) ExportImage(opts Options) error {
|
||||
name := opts.ImageName
|
||||
path := opts.Destination
|
||||
buildarg := []string{"save", "-o", path, name}
|
||||
Debug(":tea: Saving image " + name)
|
||||
s.ctx.Debug(":tea: Saving image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
|
||||
out, err := exec.Command("img", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed exporting image: "+string(out))
|
||||
}
|
||||
Info(":tea: Image " + name + " saved")
|
||||
s.ctx.Info(":tea: Image " + name + " saved")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -166,20 +167,20 @@ func (s *SimpleImg) ExtractRootfs(opts Options, keepPerms bool) error {
|
||||
os.RemoveAll(path)
|
||||
|
||||
buildarg := []string{"unpack", "-o", path, name}
|
||||
Debug(":tea: Extracting image " + name)
|
||||
s.ctx.Debug(":tea: Extracting image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
s.ctx.Spinner()
|
||||
defer s.ctx.SpinnerStop()
|
||||
|
||||
out, err := exec.Command("img", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed extracting image: "+string(out))
|
||||
}
|
||||
Debug(":tea: Image " + name + " extracted")
|
||||
s.ctx.Debug(":tea: Image " + name + " extracted")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SimpleImg) Push(opts Options) error {
|
||||
func (s *SimpleImg) Push(opts Options) error {
|
||||
name := opts.ImageName
|
||||
bus.Manager.Publish(bus.EventImagePrePush, opts)
|
||||
|
||||
@@ -188,9 +189,9 @@ func (*SimpleImg) Push(opts Options) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed pushing image: "+string(out))
|
||||
}
|
||||
Info(":tea: Pushed image:", name)
|
||||
s.ctx.Info(":tea: Pushed image:", name)
|
||||
bus.Manager.Publish(bus.EventImagePostPush, opts)
|
||||
|
||||
//Info(string(out))
|
||||
//s.ctx.Info(string(out))
|
||||
return nil
|
||||
}
|
||||
|
@@ -19,18 +19,20 @@ package backend
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
"github.com/mudler/luet/pkg/api/core/types"
|
||||
)
|
||||
|
||||
type BackendWriter struct {
|
||||
BufferedOutput bool
|
||||
Buffer *bytes.Buffer
|
||||
ctx *types.Context
|
||||
}
|
||||
|
||||
func NewBackendWriter(buffered bool) *BackendWriter {
|
||||
func NewBackendWriter(buffered bool, ctx *types.Context) *BackendWriter {
|
||||
return &BackendWriter{
|
||||
BufferedOutput: buffered,
|
||||
Buffer: &bytes.Buffer{},
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +41,7 @@ func (b *BackendWriter) Write(p []byte) (int, error) {
|
||||
return b.Buffer.Write(p)
|
||||
}
|
||||
|
||||
Msg("info", false, false, (string(p)))
|
||||
b.ctx.Msg("info", false, (string(p)))
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user