Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions cmd/argo/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package commands

import (
"fmt"
"os"
"strings"

"github.com/spf13/cobra"
Expand All @@ -21,7 +20,6 @@ import (

cmdutil "github.com/argoproj/argo-workflows/v4/util/cmd"
grpcutil "github.com/argoproj/argo-workflows/v4/util/grpc"
"github.com/argoproj/argo-workflows/v4/util/logging"
)

const (
Expand Down Expand Up @@ -140,8 +138,7 @@ If your server is behind an ingress with a path (running "argo server --base-hre
}
ctx, log, err := cmdutil.ContextWithLogger(cmd, logLevel, logFormat)
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(ctx, "Failed to create argo pre-run logger")
os.Exit(1)
cmdutil.FatalBootstrap(logFormat, err, "Failed to create argo pre-run logger")
}

cmdutil.SetGLogLevel(glogLevel)
Expand All @@ -163,8 +160,7 @@ If your server is behind an ingress with a path (running "argo server --base-hre
command.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enabled verbose logging, i.e. --loglevel debug")
cctx, log, err := cmdutil.ContextWithLogger(command, logLevel, logFormat)
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(cctx, "Failed to create argo logger")
os.Exit(1)
cmdutil.FatalBootstrap(logFormat, err, "Failed to create argo logger")
}
command.SetContext(cctx)

Expand Down
2 changes: 1 addition & 1 deletion cmd/argo/commands/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ See %s`, help.ArgoServer()),
// bind flags to env vars (https://github.com/spf13/viper/tree/v1.17.0#working-with-flags)
ctx, logger, err := cmdutil.ContextWithLogger(&command, logLevel, logFormat)
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(ctx, "Failed to create server logger")
cmdutil.FatalBootstrap(logFormat, err, "Failed to create server logger")
}
if err := viper.BindPFlags(command.Flags()); err != nil {
logger.WithError(err).WithFatal().Error(ctx, "Failed to bind flags to env vars")
Expand Down
3 changes: 1 addition & 2 deletions cmd/argo/commands/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ func NewSubmitCommand() *cobra.Command {
// Only complete files with appropriate extension.
ctx, _, err := cmdutil.ContextWithLogger(command, string(logging.Info), string(logging.Text))
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(ctx, "Failed to create submit logger")
os.Exit(1)
cmdutil.FatalBootstrap(string(logging.Text), err, "Failed to create submit logger")
}
logger := logging.RequireLoggerFromContext(ctx)
err = command.Flags().SetAnnotation("parameter-file", cobra.BashCompFilenameExt, []string{"json", "yaml", "yml"})
Expand Down
16 changes: 8 additions & 8 deletions cmd/argoexec/commands/emissary_link_artifacts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

func TestLinkInputArtifacts_Normal(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand Down Expand Up @@ -43,7 +43,7 @@ func TestLinkInputArtifacts_Normal(t *testing.T) {
}

func TestLinkInputArtifacts_MissingSourceIsSkipped(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand All @@ -68,7 +68,7 @@ func TestLinkInputArtifacts_MissingSourceIsSkipped(t *testing.T) {
// filesystem (no declared volume), must be replaced by the symlink — matching
// what the legacy SubPath bind mount shadowed.
func TestLinkInputArtifacts_OverwritesExistingFile(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand Down Expand Up @@ -97,7 +97,7 @@ func TestLinkInputArtifacts_OverwritesExistingFile(t *testing.T) {
// (e.g. a git/directory artifact at /tmp/git): linking must replace it with the
// symlink rather than failing. No declared volume → safe to clear.
func TestLinkInputArtifacts_OverwritesExistingDirectory(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand Down Expand Up @@ -127,7 +127,7 @@ func TestLinkInputArtifacts_OverwritesExistingDirectory(t *testing.T) {

// TestLinkInputArtifacts_EmptyPathSkipped covers art.Path == "".
func TestLinkInputArtifacts_EmptyPathSkipped(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand All @@ -148,7 +148,7 @@ func TestLinkInputArtifacts_EmptyPathSkipped(t *testing.T) {
// the symlink and destroy live volume data, so staging must refuse and leave the
// volume untouched.
func TestLinkInputArtifacts_RefusesOverwriteResolvingIntoVolume(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand Down Expand Up @@ -195,7 +195,7 @@ func TestLinkInputArtifacts_RefusesOverwriteResolvingIntoVolume(t *testing.T) {
// there yet, staging creates the symlink anyway (the user asked for it). Creating
// can never destroy data, so it is not gated.
func TestLinkInputArtifacts_CreateResolvingIntoVolumeAllowed(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand Down Expand Up @@ -237,7 +237,7 @@ func TestLinkInputArtifacts_CreateResolvingIntoVolumeAllowed(t *testing.T) {
// os.RemoveAll removes the symlink itself (it does not follow the final element),
// so staging safely replaces it and the symlink's old target is untouched.
func TestLinkInputArtifacts_ReplacesImageSymlinkInRootfs(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
srcBase := filepath.Join(dir, "inputs")
require.NoError(t, os.MkdirAll(srcBase, 0o755))
Expand Down
18 changes: 9 additions & 9 deletions cmd/argoexec/commands/emissary_ready_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
)

func TestWaitForSupervisorReady_ReadyAppears(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -36,7 +36,7 @@ func TestWaitForSupervisorReady_ReadyAppears(t *testing.T) {
}

func TestWaitForSupervisorReady_FailedAppears(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -53,7 +53,7 @@ func TestWaitForSupervisorReady_FailedAppears(t *testing.T) {
}

func TestWaitForSupervisorReady_AlreadyReady(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -65,7 +65,7 @@ func TestWaitForSupervisorReady_AlreadyReady(t *testing.T) {
}

func TestWaitForSupervisorReady_AlreadyFailed(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -82,7 +82,7 @@ func TestWaitForSupervisorReady_AlreadyFailed(t *testing.T) {
// path: a RUNNING marker keeps main waiting (a generous timeout means staleness
// never fires), and the later terminal READY write releases it.
func TestWaitForSupervisorReady_RunningThenReady(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -101,7 +101,7 @@ func TestWaitForSupervisorReady_RunningThenReady(t *testing.T) {
// wrote RUNNING then died without ever writing a terminal status: the marker's
// mtime goes stale past the timeout and main fails fast instead of hanging.
func TestWaitForSupervisorReady_StaleRunningPresumedDead(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -121,7 +121,7 @@ func TestWaitForSupervisorReady_StaleRunningPresumedDead(t *testing.T) {
// died before writing any marker: main bounds the wait by the timeout rather
// than blocking to the pod deadline.
func TestWaitForSupervisorReady_NeverAppearsPresumedDead(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -133,7 +133,7 @@ func TestWaitForSupervisorReady_NeverAppearsPresumedDead(t *testing.T) {
}

func TestWaitForSupervisorReady_ContextCancelled(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -150,7 +150,7 @@ func TestWaitForSupervisorReady_ContextCancelled(t *testing.T) {
// nil and mistaken for a ready supervisor. With no marker present, an explicit
// cancel must surface as an error, not success.
func TestWaitForSupervisorReady_ParentCancelledPropagates(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand Down
8 changes: 2 additions & 6 deletions cmd/argoexec/commands/root.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package commands

import (
"os"

"github.com/spf13/cobra"
"k8s.io/client-go/tools/clientcmd"

Expand Down Expand Up @@ -39,8 +37,7 @@ func NewRootCommand() *cobra.Command {
initConfig()
ctx, logger, err := cmdutil.ContextWithLogger(cmd, logLevel, logFormat)
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(cmd.Context(), "Failed to create argoexec pre-run logger")
os.Exit(1)
cmdutil.FatalBootstrap(logFormat, err, "Failed to create argoexec pre-run logger")
}

// Required: argo=true field for test filtering compatibility
Expand Down Expand Up @@ -76,8 +73,7 @@ func NewRootCommand() *cobra.Command {

ctx, logger, err := cmdutil.ContextWithLogger(&command, logLevel, logFormat)
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(command.Context(), "Failed to create argoexec logger")
os.Exit(1)
cmdutil.FatalBootstrap(logFormat, err, "Failed to create argoexec logger")
}

// Required: argo=true field for test filtering compatibility
Expand Down
6 changes: 3 additions & 3 deletions cmd/argoexec/commands/supervisor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func TestStatusMarker_Success(t *testing.T) {
}

func TestStatusMarker_FailureCapturesCause(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -94,7 +94,7 @@ func TestStatusMarker_FailureCapturesCause(t *testing.T) {
}

func TestStatusMarker_FailureWithEmptyCauseStillSignalsFailure(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
dir := t.TempDir()
statusPath := filepath.Join(dir, "status")

Expand All @@ -109,7 +109,7 @@ func TestStatusMarker_FailureWithEmptyCauseStillSignalsFailure(t *testing.T) {
}

func TestStatusMarker_BestEffortOnUnwritable(t *testing.T) {
ctx := logging.WithLogger(context.Background(), logging.InitLogger())
ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.Text))
// Path under a directory that doesn't exist — write fails, but the
// helper must not panic; supervisor's pre-main error still propagates
// via PostMain even if the marker write itself fails.
Expand Down
5 changes: 2 additions & 3 deletions cmd/workflow-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func NewRootCommand() *cobra.Command {
defer runtimeutil.HandleCrashWithContext(c.Context(), runtimeutil.PanicHandlers...)
ctx, log, err := cmdutil.ContextWithLogger(c, logLevel, logFormat)
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(c.Context(), "Failed to create workflow-controller cmd logger")
cmdutil.FatalBootstrap(logFormat, err, "Failed to create workflow-controller cmd logger")
return err
}

Expand Down Expand Up @@ -224,8 +224,7 @@ func NewRootCommand() *cobra.Command {
command.Flags().BoolVar(&workflowLevelExecutorPlugins, "workflow-level-executor-plugins", false, "enable workflow-level executor plugins")
ctx, log, err := cmdutil.ContextWithLogger(&command, logLevel, logFormat)
if err != nil {
logging.InitLogger().WithError(err).WithFatal().Error(command.Context(), "Failed to create workflow-controller logger")
os.Exit(1)
cmdutil.FatalBootstrap(logFormat, err, "Failed to create workflow-controller logger")
}

// set-up env vars for the CLI such that ARGO_* env vars can be used instead of flags
Expand Down
7 changes: 4 additions & 3 deletions test/e2e/fixtures/e2e_suite.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fixtures

import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -45,11 +46,11 @@ const (
Backfill = workflow.WorkflowFullName + "/backfill" // clean backfill workflows
)

var timeoutBias = env.LookupEnvDurationOr(logging.InitLoggerInContext(), "E2E_WAIT_TIMEOUT_BIAS", 0*time.Second)
var timeoutBias = env.LookupEnvDurationOr(logging.TestContext(context.Background()), "E2E_WAIT_TIMEOUT_BIAS", 0*time.Second)

var defaultTimeout = env.LookupEnvDurationOr(logging.InitLoggerInContext(), "E2E_WAIT_TIMEOUT", 60*time.Second) + timeoutBias
var defaultTimeout = env.LookupEnvDurationOr(logging.TestContext(context.Background()), "E2E_WAIT_TIMEOUT", 60*time.Second) + timeoutBias

var EnvFactor = env.LookupEnvIntOr(logging.InitLoggerInContext(), "E2E_ENV_FACTOR", 1)
var EnvFactor = env.LookupEnvIntOr(logging.TestContext(context.Background()), "E2E_ENV_FACTOR", 1)

// AuxContainerName returns the name of Argo's auxiliary executor container for
// the pod layout under test: "supervisor" when the controller runs the init-less
Expand Down
18 changes: 18 additions & 0 deletions util/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"fmt"
"net/url"
"os"
"strings"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -117,3 +118,20 @@ func ContextWithLogger(cmd *cobra.Command, logLevel, logType string) (context.Co
cmd.SetContext(ctx)
return ctx, logger, nil
}

// FatalBootstrap reports an error that occurred before the main logger could be
// constructed, then exits non-zero. It honours the requested log format when
// that format is parseable and falls back to JSON when it is not (the format
// flag itself may be the invalid input).
func FatalBootstrap(logFormat string, err error, msg string) {
format, ferr := logging.TypeFromStringOr(logFormat, logging.JSON)
if ferr != nil {
format = logging.JSON
}
logging.NewSlogLoggerCustom(logging.Error, format, os.Stderr).WithError(err).Error(context.Background(), msg)
if exit := logging.GetExitFunc(); exit != nil {
exit(1)
return
}
os.Exit(1)
}
15 changes: 15 additions & 0 deletions util/cmd/cmd_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"errors"
"reflect"
"testing"

Expand Down Expand Up @@ -174,3 +175,17 @@ func TestPrintVersionMismatchWarning(t *testing.T) {
})
}
}

func TestFatalBootstrap(t *testing.T) {
var code int
logging.SetExitFunc(func(c int) { code = c })
defer logging.SetExitFunc(nil)

FatalBootstrap("json", errors.New("boom"), "failed to create logger")
assert.Equal(t, 1, code)

// an unparseable format must fall back, not recurse or panic
code = 0
FatalBootstrap("not-a-format", errors.New("boom"), "failed to create logger")
assert.Equal(t, 1, code)
}
Loading