build, multiarch: support splitting build logs for --platform

Support splitting build logs for multi-arch builds ( `--platform` ) by
using `--logfile` and `--logsplit` which splits generated log file in the
convention `${file}_${platform_os}_${platform_arch}`.

Closes: https://github.com/containers/buildah/issues/3960

Signed-off-by: Aditya R <arajan@redhat.com>
This commit is contained in:
Aditya R 2022-06-06 12:03:15 +05:30 committed by Nalin Dahyabhai
parent 65c331c23a
commit 821c100105
6 changed files with 59 additions and 1 deletions

View File

@ -253,6 +253,12 @@ func buildCmd(c *cobra.Command, inputArgs []string, iopts buildOptions) error {
reporter = f
}
if c.Flag("logsplit").Changed {
if !c.Flag("logfile").Changed {
return errors.Errorf("cannot use --logsplit without --logfile")
}
}
store, err := getStore(c)
if err != nil {
return err
@ -383,6 +389,8 @@ func buildCmd(c *cobra.Command, inputArgs []string, iopts buildOptions) error {
IgnoreFile: iopts.IgnoreFile,
Labels: iopts.Label,
Layers: layers,
LogFile: iopts.Logfile,
LogSplitByPlatform: iopts.LogSplitByPlatform,
LogRusage: iopts.LogRusage,
Manifest: iopts.Manifest,
MaxPullPushRetries: maxPullPushRetries,

View File

@ -151,6 +151,12 @@ type BuildOptions struct {
// Additional tags to add to the image that we write, if we know of a
// way to add them.
AdditionalTags []string
// Logfile specifies if log output is redirected to an external file
// instead of stdout, stderr.
LogFile string
// LogByPlatform tells imagebuildah to split log to different log files
// for each platform if logging to external file was selected.
LogSplitByPlatform bool
// Log is a callback that will print a progress message. If no value
// is supplied, the message will be sent to Err (or os.Stderr, if Err
// is nil) by default.

View File

@ -398,6 +398,11 @@ environment variable. `export BUILDAH_LAYERS=true`
Log output which would be sent to standard output and standard error to the
specified file instead of to standard output and standard error.
**--logsplit** *bool-value*
If --logfile and --platform is specified following flag allows end-users to split log file for each
platform into different files with naming convention as `${logfile}_${platform-os}_${platform-arch}`.
**--manifest** *listName*
Name of the manifest list to which the built image will be added. Creates the

View File

@ -253,7 +253,25 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options define.B
}
platformOptions.Args = argsCopy
builds.Go(func() error {
thisID, thisRef, err := buildDockerfilesOnce(ctx, store, logger, logPrefix, platformOptions, paths, files)
loggerPerPlatform := logger
if platformOptions.LogFile != "" && platformOptions.LogSplitByPlatform {
logFile := platformOptions.LogFile + "_" + platformOptions.OS + "_" + platformOptions.Architecture
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return errors.Wrapf(err, "opening logfile: %q", logFile)
}
defer f.Close()
loggerPerPlatform = logrus.New()
loggerPerPlatform.SetOutput(f)
loggerPerPlatform.SetLevel(logrus.GetLevel())
stdout := f
stderr := f
reporter := f
platformOptions.Out = stdout
platformOptions.ReportWriter = reporter
platformOptions.Err = stderr
}
thisID, thisRef, err := buildDockerfilesOnce(ctx, store, loggerPerPlatform, logPrefix, platformOptions, paths, files)
if err != nil {
return err
}

View File

@ -68,6 +68,7 @@ type BudResults struct {
Iidfile string
Label []string
Logfile string
LogSplitByPlatform bool
Manifest string
NoHosts bool
NoCache bool
@ -211,6 +212,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.IntVar(&flags.Jobs, "jobs", 1, "how many stages to run in parallel")
fs.StringArrayVar(&flags.Label, "label", []string{}, "set metadata for an image (default [])")
fs.StringVar(&flags.Logfile, "logfile", "", "log to `file` instead of stdout/stderr")
fs.BoolVar(&flags.LogSplitByPlatform, "logsplit", false, "split logfile to different files for each platform")
fs.Int("loglevel", 0, "NO LONGER USED, flag ignored, and hidden")
if err := fs.MarkHidden("loglevel"); err != nil {
panic(fmt.Sprintf("error marking the loglevel flag as hidden: %v", err))

View File

@ -1704,6 +1704,25 @@ function _test_http() {
test -s ${TEST_SCRATCH_DIR}/logfile
}
@test "bud-logfile-with-split-logfile-by-platform" {
mytmpdir=${TEST_SCRATCH_DIR}/my-dir
mkdir -p $mytmpdir
cat > $mytmpdir/Containerfile << _EOF
FROM alpine
COPY . .
_EOF
rm -f ${TEST_SCRATCH_DIR}/logfile
run_buildah build --logfile ${TEST_SCRATCH_DIR}/logfile --logsplit --platform linux/arm64,linux/amd64 $WITH_POLICY_JSON ${mytmpdir}
run cat ${TEST_SCRATCH_DIR}/logfile_linux_arm64
expect_output --substring "FROM alpine"
expect_output --substring "[linux/arm64]"
run cat ${TEST_SCRATCH_DIR}/logfile_linux_amd64
expect_output --substring "FROM alpine"
expect_output --substring "[linux/amd64]"
}
@test "bud with ARGS" {
_prefetch alpine
target=alpine-image