mirror of
https://github.com/mudler/luet.git
synced 2025-09-06 17:50:34 +00:00
backend: Add realtime output on building phase
The realtime output could be configured through LUET_GENERAL__SHOW_BUILD_OUTPUT environment variable or related config option or through `--live-output` option.
This commit is contained in:
@@ -83,6 +83,8 @@ Build packages specifying multiple definition trees:
|
|||||||
LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
|
LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
|
||||||
LuetCfg.Viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate"))
|
LuetCfg.Viper.BindPFlag("solver.rate", cmd.Flags().Lookup("solver-rate"))
|
||||||
LuetCfg.Viper.BindPFlag("solver.max_attempts", cmd.Flags().Lookup("solver-attempts"))
|
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) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
@@ -155,6 +157,8 @@ Build packages specifying multiple definition trees:
|
|||||||
LuetCfg.GetSolverOptions().Discount = float32(discount)
|
LuetCfg.GetSolverOptions().Discount = float32(discount)
|
||||||
LuetCfg.GetSolverOptions().MaxAttempts = attempts
|
LuetCfg.GetSolverOptions().MaxAttempts = attempts
|
||||||
|
|
||||||
|
LuetCfg.GetGeneral().ShowBuildOutput = LuetCfg.Viper.GetBool("general.show_build_output")
|
||||||
|
|
||||||
Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
|
Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
|
||||||
|
|
||||||
opts := compiler.NewDefaultCompilerOptions()
|
opts := compiler.NewDefaultCompilerOptions()
|
||||||
@@ -317,6 +321,7 @@ func init() {
|
|||||||
buildCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
|
buildCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate")
|
||||||
buildCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
buildCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
||||||
buildCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
|
buildCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
|
||||||
|
buildCmd.Flags().Bool("live-output", LuetCfg.GetGeneral().ShowBuildOutput, "Enable live output of the build phase.")
|
||||||
|
|
||||||
buildCmd.Flags().Bool("pretend", false, "Just print what packages will be compiled")
|
buildCmd.Flags().Bool("pretend", false, "Just print what packages will be compiled")
|
||||||
|
|
||||||
|
@@ -16,8 +16,15 @@
|
|||||||
package backend
|
package backend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/google/go-containerregistry/pkg/crane"
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
"github.com/mudler/luet/pkg/compiler"
|
"github.com/mudler/luet/pkg/compiler"
|
||||||
|
"github.com/mudler/luet/pkg/config"
|
||||||
|
. "github.com/mudler/luet/pkg/logger"
|
||||||
|
|
||||||
|
"github.com/google/go-containerregistry/pkg/crane"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -41,3 +48,45 @@ func NewBackend(s string) compiler.CompilerBackend {
|
|||||||
}
|
}
|
||||||
return compilerBackend
|
return compilerBackend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runCommand(cmd *exec.Cmd) (string, error) {
|
||||||
|
ans := ""
|
||||||
|
writer := NewBackendWriter(!config.LuetCfg.GetGeneral().ShowBuildOutput)
|
||||||
|
|
||||||
|
if config.LuetCfg.GetGeneral().ShowBuildOutput {
|
||||||
|
// We have realtime output from command. Quiet spinner.
|
||||||
|
SpinnerStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
Spinner(22)
|
||||||
|
} else {
|
||||||
|
ans = writer.GetCombinedOutput()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ans, nil
|
||||||
|
}
|
||||||
|
@@ -56,10 +56,11 @@ func (*SimpleDocker) BuildImage(opts compiler.CompilerBackendOptions) error {
|
|||||||
Info(":whale2: Building image " + name)
|
Info(":whale2: Building image " + name)
|
||||||
cmd := exec.Command("docker", buildarg...)
|
cmd := exec.Command("docker", buildarg...)
|
||||||
cmd.Dir = path
|
cmd.Dir = path
|
||||||
out, err := cmd.CombinedOutput()
|
_, err := runCommand(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Failed building image: "+string(out))
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Info(":whale: Building image " + name + " done")
|
Info(":whale: Building image " + name + " done")
|
||||||
|
|
||||||
if os.Getenv("DOCKER_SQUASH") == "true" {
|
if os.Getenv("DOCKER_SQUASH") == "true" {
|
||||||
@@ -77,12 +78,6 @@ func (*SimpleDocker) BuildImage(opts compiler.CompilerBackendOptions) error {
|
|||||||
Info(":whale: Squashing image " + name + " done")
|
Info(":whale: Squashing image " + name + " done")
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.LuetCfg.GetGeneral().ShowBuildOutput {
|
|
||||||
Info(string(out))
|
|
||||||
} else {
|
|
||||||
Debug(string(out))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,17 +44,17 @@ func (*SimpleImg) BuildImage(opts compiler.CompilerBackendOptions) error {
|
|||||||
dockerfileName := opts.DockerFileName
|
dockerfileName := opts.DockerFileName
|
||||||
|
|
||||||
buildarg := []string{"build", "-f", dockerfileName, "-t", name, context}
|
buildarg := []string{"build", "-f", dockerfileName, "-t", name, context}
|
||||||
Spinner(22)
|
|
||||||
defer SpinnerStop()
|
|
||||||
Info(":tea: Building image " + name)
|
Info(":tea: Building image " + name)
|
||||||
cmd := exec.Command("img", buildarg...)
|
cmd := exec.Command("img", buildarg...)
|
||||||
cmd.Dir = path
|
cmd.Dir = path
|
||||||
out, err := cmd.CombinedOutput()
|
_, err := runCommand(cmd)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Failed building image: "+string(out))
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Info(":tea: Building image " + name + " done")
|
Info(":tea: Building image " + name + " done")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() }
|
Reference in New Issue
Block a user