mirror of
https://github.com/mudler/luet.git
synced 2025-06-24 14:31:55 +00:00
Merge pull request #183 from mudler/docker-debug-output
Add realtime output for building phase
This commit is contained in:
commit
101df40eec
@ -83,6 +83,8 @@ Build packages specifying multiple definition trees:
|
||||
LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
|
||||
LuetCfg.Viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate"))
|
||||
LuetCfg.Viper.BindPFlag("solver.max_attempts", cmd.Flags().Lookup("solver-attempts"))
|
||||
LuetCfg.Viper.BindPFlag("general.show_build_output", cmd.Flags().Lookup("live-output"))
|
||||
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
@ -155,6 +157,8 @@ Build packages specifying multiple definition trees:
|
||||
LuetCfg.GetSolverOptions().Discount = float32(discount)
|
||||
LuetCfg.GetSolverOptions().MaxAttempts = attempts
|
||||
|
||||
LuetCfg.GetGeneral().ShowBuildOutput = LuetCfg.Viper.GetBool("general.show_build_output")
|
||||
|
||||
Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
|
||||
|
||||
opts := compiler.NewDefaultCompilerOptions()
|
||||
@ -317,6 +321,7 @@ func init() {
|
||||
buildCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
|
||||
buildCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
||||
buildCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
|
||||
buildCmd.Flags().Bool("live-output", LuetCfg.GetGeneral().ShowBuildOutput, "Enable live output of the build phase.")
|
||||
|
||||
buildCmd.Flags().Bool("pretend", false, "Just print what packages will be compiled")
|
||||
|
||||
|
@ -16,8 +16,14 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"github.com/google/go-containerregistry/pkg/crane"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"github.com/mudler/luet/pkg/compiler"
|
||||
"github.com/mudler/luet/pkg/config"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/crane"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -41,3 +47,38 @@ func NewBackend(s string) compiler.CompilerBackend {
|
||||
}
|
||||
return compilerBackend
|
||||
}
|
||||
|
||||
func runCommand(cmd *exec.Cmd) (string, error) {
|
||||
ans := ""
|
||||
writer := NewBackendWriter(!config.LuetCfg.GetGeneral().ShowBuildOutput)
|
||||
|
||||
cmd.Stdout = writer
|
||||
cmd.Stderr = writer
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Failed starting build")
|
||||
}
|
||||
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Failed waiting for building command")
|
||||
}
|
||||
|
||||
res := cmd.ProcessState.ExitCode()
|
||||
if res != 0 {
|
||||
errMsg := fmt.Sprintf("Failed building image (exiting with %d)", res)
|
||||
if !config.LuetCfg.GetGeneral().ShowBuildOutput {
|
||||
errMsg = fmt.Sprintf("Failed building image (exiting with %d): %s",
|
||||
res, writer.GetCombinedOutput())
|
||||
}
|
||||
|
||||
return "", errors.Wrap(err, errMsg)
|
||||
}
|
||||
|
||||
if !config.LuetCfg.GetGeneral().ShowBuildOutput {
|
||||
ans = writer.GetCombinedOutput()
|
||||
}
|
||||
|
||||
return ans, nil
|
||||
}
|
||||
|
@ -53,19 +53,31 @@ func (*SimpleDocker) BuildImage(opts compiler.CompilerBackendOptions) error {
|
||||
}
|
||||
buildarg := []string{"build", "-f", dockerfileName, "-t", name, context}
|
||||
|
||||
if !config.LuetCfg.GetGeneral().ShowBuildOutput {
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
}
|
||||
|
||||
Info(":whale2: Building image " + name)
|
||||
cmd := exec.Command("docker", buildarg...)
|
||||
cmd.Dir = path
|
||||
out, err := cmd.CombinedOutput()
|
||||
_, err := runCommand(cmd)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed building image: "+string(out))
|
||||
return err
|
||||
}
|
||||
|
||||
if !config.LuetCfg.GetGeneral().ShowBuildOutput {
|
||||
SpinnerStop()
|
||||
}
|
||||
|
||||
Info(":whale: Building image " + name + " done")
|
||||
|
||||
if os.Getenv("DOCKER_SQUASH") == "true" {
|
||||
Info(":whale: Squashing image " + name)
|
||||
var client *docker.Client
|
||||
|
||||
Spinner(22)
|
||||
|
||||
client, err = docker.NewClientFromEnv()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not connect to the Docker daemon")
|
||||
@ -74,13 +86,8 @@ func (*SimpleDocker) BuildImage(opts compiler.CompilerBackendOptions) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed squashing image")
|
||||
}
|
||||
Info(":whale: Squashing image " + name + " done")
|
||||
}
|
||||
|
||||
if config.LuetCfg.GetGeneral().ShowBuildOutput {
|
||||
Info(string(out))
|
||||
} else {
|
||||
Debug(string(out))
|
||||
Info(":whale: Squashing image " + name + " done")
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -101,11 +108,16 @@ func (*SimpleDocker) DownloadImage(opts compiler.CompilerBackendOptions) error {
|
||||
name := opts.ImageName
|
||||
buildarg := []string{"pull", name}
|
||||
Debug(":whale: Downloading image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
cmd := exec.Command("docker", buildarg...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed pulling image: "+string(out))
|
||||
}
|
||||
|
||||
Info(":whale: Downloaded image:", name)
|
||||
return nil
|
||||
}
|
||||
@ -142,6 +154,10 @@ func (*SimpleDocker) RemoveImage(opts compiler.CompilerBackendOptions) error {
|
||||
func (*SimpleDocker) Push(opts compiler.CompilerBackendOptions) error {
|
||||
name := opts.ImageName
|
||||
pusharg := []string{"push", name}
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
out, err := exec.Command("docker", pusharg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed pushing image: "+string(out))
|
||||
@ -170,6 +186,10 @@ func (*SimpleDocker) ExportImage(opts compiler.CompilerBackendOptions) error {
|
||||
|
||||
buildarg := []string{"save", name, "-o", path}
|
||||
Debug(":whale: Saving image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
out, err := exec.Command("docker", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed exporting image: "+string(out))
|
||||
@ -194,10 +214,16 @@ func (b *SimpleDocker) ExtractRootfs(opts compiler.CompilerBackendOptions, keepP
|
||||
defer os.RemoveAll(tempexport) // clean up
|
||||
|
||||
imageExport := filepath.Join(tempexport, "image.tar")
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
if err := b.ExportImage(compiler.CompilerBackendOptions{ImageName: name, Destination: imageExport}); err != nil {
|
||||
return errors.Wrap(err, "failed while extracting rootfs for "+name)
|
||||
}
|
||||
|
||||
SpinnerStop()
|
||||
|
||||
src := imageExport
|
||||
|
||||
if src == "" && opts.ImageName != "" {
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mudler/luet/pkg/compiler"
|
||||
"github.com/mudler/luet/pkg/config"
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@ -44,17 +45,23 @@ func (*SimpleImg) BuildImage(opts compiler.CompilerBackendOptions) error {
|
||||
dockerfileName := opts.DockerFileName
|
||||
|
||||
buildarg := []string{"build", "-f", dockerfileName, "-t", name, context}
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
Info(":tea: Building image " + name)
|
||||
|
||||
if !config.LuetCfg.GetGeneral().ShowBuildOutput {
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
}
|
||||
|
||||
cmd := exec.Command("img", buildarg...)
|
||||
cmd.Dir = path
|
||||
out, err := cmd.CombinedOutput()
|
||||
|
||||
_, err := runCommand(cmd)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed building image: "+string(out))
|
||||
return err
|
||||
}
|
||||
|
||||
Info(":tea: Building image " + name + " done")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -73,11 +80,13 @@ func (*SimpleImg) RemoveImage(opts compiler.CompilerBackendOptions) error {
|
||||
}
|
||||
|
||||
func (*SimpleImg) DownloadImage(opts compiler.CompilerBackendOptions) error {
|
||||
|
||||
name := opts.ImageName
|
||||
buildarg := []string{"pull", name}
|
||||
|
||||
Debug(":tea: Downloading image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
cmd := exec.Command("img", buildarg...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
@ -138,6 +147,10 @@ func (*SimpleImg) ExportImage(opts compiler.CompilerBackendOptions) error {
|
||||
path := opts.Destination
|
||||
buildarg := []string{"save", "-o", path, name}
|
||||
Debug(":tea: Saving image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
out, err := exec.Command("img", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed exporting image: "+string(out))
|
||||
@ -158,8 +171,13 @@ func (s *SimpleImg) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerm
|
||||
}
|
||||
|
||||
os.RemoveAll(path)
|
||||
|
||||
buildarg := []string{"unpack", "-o", path, name}
|
||||
Debug(":tea: Extracting image " + name)
|
||||
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
|
||||
out, err := exec.Command("img", buildarg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed extracting image: "+string(out))
|
||||
|
45
pkg/compiler/backend/writer.go
Normal file
45
pkg/compiler/backend/writer.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright © 2021 Daniele Rondina <geaaru@sabayonlinux.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 backend
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
)
|
||||
|
||||
type BackendWriter struct {
|
||||
BufferedOutput bool
|
||||
Buffer bytes.Buffer
|
||||
}
|
||||
|
||||
func NewBackendWriter(buffered bool) *BackendWriter {
|
||||
return &BackendWriter{
|
||||
BufferedOutput: buffered,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BackendWriter) Write(p []byte) (int, error) {
|
||||
if b.BufferedOutput {
|
||||
return b.Buffer.Write(p)
|
||||
} else {
|
||||
Msg("info", false, false, (string(p)))
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (b *BackendWriter) Close() error { return nil }
|
||||
func (b *BackendWriter) GetCombinedOutput() string { return b.Buffer.String() }
|
@ -148,8 +148,6 @@ func (cs *LuetCompiler) CompileWithReverseDeps(keepPermissions bool, ps Compilat
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) CompileParallel(keepPermissions bool, ps CompilationSpecs) ([]Artifact, []error) {
|
||||
Spinner(22)
|
||||
defer SpinnerStop()
|
||||
all := make(chan CompilationSpec)
|
||||
artifacts := []Artifact{}
|
||||
mutex := &sync.Mutex{}
|
||||
|
@ -173,7 +173,7 @@ func level2AtomicLevel(level string) zap.AtomicLevel {
|
||||
}
|
||||
}
|
||||
|
||||
func msg(level string, withoutColor bool, msg ...interface{}) {
|
||||
func Msg(level string, withoutColor, ln bool, msg ...interface{}) {
|
||||
var message string
|
||||
var confLevel, msgLevel int
|
||||
|
||||
@ -219,11 +219,16 @@ func msg(level string, withoutColor bool, msg ...interface{}) {
|
||||
log2File(level, message)
|
||||
}
|
||||
|
||||
fmt.Println(levelMsg)
|
||||
if ln {
|
||||
fmt.Println(levelMsg)
|
||||
} else {
|
||||
fmt.Print(levelMsg)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func Warning(mess ...interface{}) {
|
||||
msg("warning", false, mess...)
|
||||
Msg("warning", false, true, mess...)
|
||||
if LuetCfg.GetGeneral().FatalWarns {
|
||||
os.Exit(2)
|
||||
}
|
||||
@ -235,23 +240,23 @@ func Debug(mess ...interface{}) {
|
||||
mess = append([]interface{}{fmt.Sprintf("DEBUG (%s:#%d:%v)",
|
||||
path.Base(file), line, runtime.FuncForPC(pc).Name())}, mess...)
|
||||
}
|
||||
msg("debug", false, mess...)
|
||||
Msg("debug", false, true, mess...)
|
||||
}
|
||||
|
||||
func DebugC(mess ...interface{}) {
|
||||
msg("debug", true, mess...)
|
||||
Msg("debug", true, true, mess...)
|
||||
}
|
||||
|
||||
func Info(mess ...interface{}) {
|
||||
msg("info", false, mess...)
|
||||
Msg("info", false, true, mess...)
|
||||
}
|
||||
|
||||
func InfoC(mess ...interface{}) {
|
||||
msg("info", true, mess...)
|
||||
Msg("info", true, true, mess...)
|
||||
}
|
||||
|
||||
func Error(mess ...interface{}) {
|
||||
msg("error", false, mess...)
|
||||
Msg("error", false, true, mess...)
|
||||
}
|
||||
|
||||
func Fatal(mess ...interface{}) {
|
||||
|
Loading…
Reference in New Issue
Block a user