Skip to content

feat: archive init and wait container logs. Fixes #12640#16267

Open
myzk-a wants to merge 22 commits into
argoproj:mainfrom
myzk-a:feat/archive-system-container-logs
Open

feat: archive init and wait container logs. Fixes #12640#16267
myzk-a wants to merge 22 commits into
argoproj:mainfrom
myzk-a:feat/archive-system-container-logs

Conversation

@myzk-a

@myzk-a myzk-a commented Jun 13, 2026

Copy link
Copy Markdown

Fixes #12640

Heads-up on the diff size (for reviewers): GitHub shows +2,567 / 50 files, but ~1,880 lines (~73%) are generated by make codegen — the quick-start-*.yaml manifests, CRD manifests under manifests/base/crds/, generated.pb.go, openapi_generated.go, swagger.json / schema.json, zz_generated.deepcopy.go, generated.proto, docs/fields.md / executor_swagger.md, and the Java SDK docs.

The hand-written change is ~690 lines, of which ~370 is tests and ~75 is docs. The core logic is only ~240 lines, concentrated in:

  • cmd/argoexec/commands/logs.go / init.go / auxiliary.go
  • workflow/executor/executor.go
  • workflow/controller/workflowpod.go
  • util/logging/slog.go
  • the type definitions in pkg/apis/workflow/v1alpha1/

Motivation

Today Argo only archives the main container's logs. When a Pod is garbage collected, the logs of Argo's own system containers — the init container (which loads input artifacts) and the wait container (which saves outputs and logs), or the single supervisor container that plays both roles under the init-less pod layout (#16161) — are lost forever.

This makes it hard to debug problems that happen outside the user's main container after the Pod is gone, for example:

  • artifact upload failures or other errors in wait,
  • reviewing which input artifacts the init container loaded.

This PR lets users opt in to archiving the system container logs as artifacts, controlled independently from archiveLogs so you only pay to store them when you need them.

Modifications

Added a new archiveSystemContainerLogs flag, settable at the controller config-map, workflow spec, or template level, following the same priority rules as the existing archiveLogs.

Since #16161 introduced the opt-in init-less pod layout, the set of system containers depends on the layout, and this PR supports both:

Legacy layout Init-less layout
Archived artifacts init-logs, wait-logs supervisor-logs
When input artifact loading fails Nothing is archived — init fails and wait never starts (documented limitation) supervisor-logs is archived, because the supervisor still runs its post-main phase

Architecture (after this change)

The system containers tee their own logs into per-container combined files on the shared /var/run/argo emptyDir volume — the same convention the emissary already uses for main. The auxiliary container (wait, or supervisor in init-less mode) then reads those files back in SaveLogs and uploads each as an artifact, alongside the existing main-logs. The tee is unconditional (the flag is not yet readable at that point); the archiving decision is made once, in SaveLogs.

flowchart TD
    subgraph Pod["Workflow Pod (legacy layout)"]
        direction TB
        Init["init container<br/>(argoexec init)"]
        Main["main container<br/>(user cmd via emissary)"]
        Wait["wait container<br/>(argoexec wait)"]
        Vol[("/var/run/argo/ctr<br/>shared emptyDir<br/>init/combined · main/combined · wait/combined")]
        Init -- tee --> Vol
        Main -- emissary tee --> Vol
        Wait -- tee --> Vol
        Vol -- "wait reads back (SaveLogs)" --> Wait
    end
    Wait -- upload --> Store["Artifact storage<br/>main-logs · init-logs (new) · wait-logs (new)"]
Loading
flowchart TD
    subgraph Pod2["Workflow Pod (init-less layout)"]
        direction TB
        Sup["supervisor container<br/>(argoexec supervisor)"]
        Main2["main container<br/>(user cmd via emissary)"]
        Vol2[("/var/run/argo/ctr<br/>shared emptyDir<br/>supervisor/combined · main/combined")]
        Sup -- tee --> Vol2
        Main2 -- emissary tee --> Vol2
        Vol2 -- "supervisor reads back (SaveLogs)" --> Sup
    end
    Sup -- upload --> Store2["Artifact storage<br/>main-logs · supervisor-logs (new)"]
Loading
  • Type / API (pkg/apis/workflow/v1alpha1/): added the ArchiveSystemContainerLogs field to ArtifactRepository and the workflow/template types, plus a SaveSystemContainerLogsAsArtifact() helper mirroring the existing SaveLogsAsArtifact().
  • Controller (workflow/controller/workflowpod.go): added IsArchiveSystemContainerLogs(tmpl), a faithful copy of IsArchiveLogs with the same controller(on) > template > workflow > controller(off) priority.
  • Executor:
    • cmd/argoexec/commands/auxiliary.go: the tee lives in runAuxiliaryContainer, the lifecycle scaffolding shared by the legacy wait command and the init-less supervisor command, so both layouts are covered in one place. The legacy-only init command (init.go) sets up its own tee, since it does not go through runAuxiliaryContainer. A tee setup failure is treated as a log-archive failure and does not block the container's primary work.
    • util/logging/slog.go: added TeeLogger and a multiHandler so a logger can fan out to its original destination and the combined file, preserving fields, format, and hooks.
    • workflow/executor/executor.go: SaveLogs derives the system container names from the pod layout (common.IsInitlessPod()) and uploads their combined files as <container>-logs artifacts when the flag is set. The auxiliary container's own log is saved last so it includes the preceding save operations; a missing combined file is skipped via fs.ErrNotExist as a safety net for tee setup failure.
  • UI (ui/src/shared/services/workflows-service.ts): dropped the container === 'main' restriction so archived logs of non-main containers can be viewed after the Pod is gone.

Verification

  • Unit tests:
    • workflow/executor/executor_test.goTestSaveLogs: covers each flag combination, the ErrNotExist skip, that the auxiliary container is saved last, and the init-less cases (t.Setenv(common.EnvVarInitlessPod, "true") switches the targets to supervisor).
    • cmd/argoexec/commands/logs_test.goTest_teeContainerLogs: combined file creation and write tee-through.
  • E2E tests (layout-aware via fixtures.AuxContainerName() / E2E_INITLESS, exercised by both the regular and the initless: true CI dimensions):
    • TestArchiveSystemContainerLogs — verifies main-logs and the per-layout system log artifacts exist on a succeeded Pod.
    • TestArchiveSystemContainerLogsWhenArtifactLoadFails — legacy: a failing init container still ends cleanly in the WorkflowError phase (regression guard for the tee added in init.go); init-less: supervisor-logs is archived even though pre-main failed.
  • make pre-commit -B passes (codegen + lint + docs + features-validate), and go build ./... is clean.

Documentation

  • Added an "Archiving System Container Logs" section (with a "Limitations" subsection) to docs/configure-archive-logs.md, including an example manifest and the init-less behavior.
  • Added a feature note at .features/pending/archive-system-container-logs.md.
  • Documented limitations: in the legacy layout a failing init container is not captured, because the wait container never starts to archive it (the init-less layout does capture this case).

AI

Claude Code was used to help review the implementation, write tests, and draft the docs, commit messages, and this PR description. All changes were reviewed by the author.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Added archiveSystemContainerLogs to opt-in archiving of Argo system container logs (init/wait in legacy pods, supervisor in init-less) as init-logs, wait-logs, or supervisor-logs.
    • Supports template/workflow/controller override with the same priority model as archiveLogs.
  • Bug Fixes
    • Improved UI archived-log retrieval for non-main containers.
  • Documentation
    • Added field documentation, config examples, and limitations.
  • Tests
    • Added unit and e2e coverage, including artifact-load failure and init-less scenarios.

myzk-a added 6 commits June 13, 2026 23:09
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
@myzk-a
myzk-a marked this pull request as ready for review June 14, 2026 02:48
@myzk-a
myzk-a requested review from a team, Joibel and terrytangyuan as code owners June 14, 2026 02:48
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 13b6a6c8-cce7-4c35-9d5a-7db694ebabf9

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6cb21 and 7c47be2.

⛔ Files ignored due to path filters (7)
  • api/openapi-spec/swagger.json is excluded by !**/api/openapi-spec/*.json
  • pkg/apis/workflow/v1alpha1/openapi_generated.go is excluded by !**/*_generated.go
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1WorkflowSpec.md is excluded by !**/sdks/java/client/**
📒 Files selected for processing (22)
  • api/jsonschema/schema.json
  • docs/executor_swagger.md
  • docs/fields.md
  • manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
  • manifests/base/crds/full/argoproj.io_cronworkflows.yaml
  • manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/full/argoproj.io_workflows.yaml
  • manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/full/argoproj.io_workflowtasksets.yaml
  • manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
  • manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtasksets.yaml
  • manifests/quick-start-minimal.yaml
  • manifests/quick-start-mysql.yaml
  • manifests/quick-start-postgres.yaml
  • manifests/quick-start-telemetry.yaml
  • pkg/apis/workflow/v1alpha1/artifact_repository_types.go
  • pkg/apis/workflow/v1alpha1/generated.proto
  • pkg/apis/workflow/v1alpha1/workflow_types.go
  • pkg/plugins/executor/swagger.yml
  • workflow/controller/workflowpod_build_test.go
🚧 Files skipped from review as they are similar to previous changes (18)
  • manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml
  • docs/executor_swagger.md
  • pkg/plugins/executor/swagger.yml
  • pkg/apis/workflow/v1alpha1/artifact_repository_types.go
  • manifests/base/crds/minimal/argoproj.io_workflowtasksets.yaml
  • pkg/apis/workflow/v1alpha1/workflow_types.go
  • pkg/apis/workflow/v1alpha1/generated.proto
  • manifests/quick-start-minimal.yaml
  • manifests/quick-start-mysql.yaml
  • manifests/quick-start-telemetry.yaml
  • docs/fields.md
  • api/jsonschema/schema.json
  • manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
  • manifests/base/crds/full/argoproj.io_workflows.yaml
  • manifests/base/crds/full/argoproj.io_cronworkflows.yaml
  • manifests/base/crds/full/argoproj.io_workflowtasksets.yaml

📝 Walkthrough

Walkthrough

Adds the opt-in archiveSystemContainerLogs setting across API schemas, controller resolution, executor log capture, artifact saving, documentation, UI retrieval, and end-to-end tests. Init-less workflows archive supervisor logs instead of init/wait logs.

Changes

Archive System Container Logs

Layer / File(s) Summary
API types and configuration contracts
pkg/apis/workflow/..., api/jsonschema/schema.json, pkg/plugins/executor/swagger.yml, docs/fields.md, docs/executor_swagger.md
Adds the optional boolean to workflow types, protobuf, schemas, Swagger models, and field documentation.
Controller and execution flow
workflow/controller/..., workflow/executor/..., util/logging/slog.go, cmd/argoexec/commands/...
Resolves configuration precedence, tees init/wait/supervisor logs, creates required auxiliary containers, and archives main and system-container artifacts independently.
Resource schemas and manifests
manifests/base/crds/..., manifests/quick-start-*.yaml
Adds the boolean field to generated CRD and quick-start schema definitions.
UI, documentation, and validation
ui/src/shared/services/workflows-service.ts, docs/configure-archive-logs.md, .features/pending/..., test/e2e/..., workflow/executor/executor_test.go, workflow/controller/workflowpod_initless_test.go, cmd/argoexec/commands/logs_test.go
Extends archived-log retrieval, documents artifact names and limitations, and tests legacy/init-less behavior, failures, missing files, and flag combinations.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: area/controller

Suggested reviewers: terrytangyuan, joibel

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, conventional, and accurately summarizes the main change to archive init and wait logs.
Description check ✅ Passed The description includes the required issue link and all template sections: Motivation, Modifications, Verification, Documentation, and AI.
Linked Issues check ✅ Passed The code and docs implement archiving for init and wait logs, satisfying #12640's request to extend archived logs beyond main containers.
Out of Scope Changes check ✅ Passed The extra init-less/supervisor support and generated artifacts are directly tied to the log-archiving feature, with no unrelated changes evident.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.44.1)
manifests/quick-start-minimal.yaml

ast-grep skipped this file: it is too large to scan (11962847 bytes)

manifests/quick-start-mysql.yaml

ast-grep skipped this file: it is too large to scan (11965039 bytes)

manifests/quick-start-postgres.yaml

ast-grep skipped this file: it is too large to scan (11964973 bytes)

  • 1 others
🔧 Checkov (3.3.8)
manifests/quick-start-minimal.yaml

Checkov skipped this file: it is too large to scan (11962847 bytes)

manifests/quick-start-mysql.yaml

Checkov skipped this file: it is too large to scan (11965039 bytes)

manifests/quick-start-postgres.yaml

Checkov skipped this file: it is too large to scan (11964973 bytes)

  • 1 others
🔧 Trivy (0.72.0)

Trivy execution failed: 2026-07-17T03:43:36Z FATAL Fatal error run error: fs scan error: scan error: scan failed: failed analysis: post analysis error: post analysis error: cloudformation scan error: fs filter error: fs filter error: walk error range error: stat .coderabbit-oasdiff.yaml: no such file or directory: range error: stat .coderabbit-oasdiff.yaml: no such file or directory


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
test/e2e/functional_test.go (1)

61-74: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Consider also asserting init-logs absence.

The comment documents that init-logs should be absent since wait never starts, but the test only checks status.Phase. Asserting the node's outputs don't contain init-logs would make this regression guard more precise and self-documenting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/functional_test.go` around lines 61 - 74, The regression test in
TestArchiveSystemContainerLogsWhenInitFails only asserts the workflow phase, but
it should also verify the documented behavior that init-logs is absent when wait
never starts. Update the ExpectWorkflow assertion to inspect the workflow
status/nodes and confirm the init node or its outputs do not contain init-logs,
using the existing TestArchiveSystemContainerLogsWhenInitFails and status.Phase
checks as the anchor for the new assertion.
workflow/executor/executor.go (1)

748-759: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider logging when system container logs are skipped.

When fs.ErrNotExist is hit for init/wait, the artifact is silently dropped with no trace. Since this is the documented failure mode for the feature's main debugging use case, a debug-level log noting the skip would aid troubleshooting without altering behavior.

💡 Proposed addition
 				if err != nil {
 					if errors.Is(err, fs.ErrNotExist) {
+						logging.RequireLoggerFromContext(ctx).WithField("container", containerName).Debug(ctx, "system container combined log file not found, skipping")
 						continue
 					}
 					we.AddError(ctx, err)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@workflow/executor/executor.go` around lines 748 - 759, When `archiveSystem`
is enabled in `we.saveContainerLogs` handling, the `fs.ErrNotExist` branch for
`common.InitContainerName` and `common.WaitContainerName` currently skips
artifacts silently; add a debug-level log in this branch so skipped system
container logs are traceable without changing behavior. Use the existing
`archiveSystem` loop in `executor.go` and the `saveContainerLogs` call site to
include the container name and that the logs were not found.
workflow/executor/executor_test.go (1)

676-697: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Strengthen "skip init and wait" test assertion.

The loop over we.errors is vacuously true if we.errors is empty, so the test doesn't actually assert that no errors were recorded — only that if there happen to be any, none are fs.ErrNotExist. Add an explicit emptiness check to make the intended invariant a hard assertion.

✅ Proposed fix
 		we.SaveLogs(ctx)
 
+		require.Empty(t, we.errors, "should not record any error when combined file does not exist")
 		for _, err := range we.errors {
 			assert.NotErrorIs(t, err, fs.ErrNotExist, "should not be a fatal error when combined file does not exist")
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@workflow/executor/executor_test.go` around lines 676 - 697, The "skip init
and wait when combined file does not exist" test in WorkflowExecutor.SaveLogs is
too weak because iterating over we.errors does not assert that any errors were
recorded. Update the test to explicitly assert that we.errors is empty after
calling SaveLogs, while keeping the existing fs.ErrNotExist check for any
unexpected entries, so the invariant is enforced by the test itself.
cmd/argoexec/commands/logs_test.go (1)

33-48: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant double-close via explicit call plus deferred closer().

Line 42 calls closer() explicitly to flush before reading the file, and line 39's defer closer() will also fire on return, closing the same *os.File twice. This is functionally harmless (f.Close() errors are swallowed), but a cleaner pattern would drop the redundant defer or provide the production code with an explicit flush/close split, since relying on double-close obscures intent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/argoexec/commands/logs_test.go` around lines 33 - 48, The test in
logs_test.go is closing the same tee container log handle twice by both
deferring closer in the t.Run body and calling closer explicitly before reading
the combined file. Update the test to use a single close path: either remove the
deferred closer and close once at the flush point, or adjust
teeContainerLogs/closer semantics so the test can explicitly flush then close
without a redundant second call. Use the teeContainerLogs and closer symbols to
keep the intent clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@cmd/argoexec/commands/logs_test.go`:
- Around line 33-48: The test in logs_test.go is closing the same tee container
log handle twice by both deferring closer in the t.Run body and calling closer
explicitly before reading the combined file. Update the test to use a single
close path: either remove the deferred closer and close once at the flush point,
or adjust teeContainerLogs/closer semantics so the test can explicitly flush
then close without a redundant second call. Use the teeContainerLogs and closer
symbols to keep the intent clear.

In `@test/e2e/functional_test.go`:
- Around line 61-74: The regression test in
TestArchiveSystemContainerLogsWhenInitFails only asserts the workflow phase, but
it should also verify the documented behavior that init-logs is absent when wait
never starts. Update the ExpectWorkflow assertion to inspect the workflow
status/nodes and confirm the init node or its outputs do not contain init-logs,
using the existing TestArchiveSystemContainerLogsWhenInitFails and status.Phase
checks as the anchor for the new assertion.

In `@workflow/executor/executor_test.go`:
- Around line 676-697: The "skip init and wait when combined file does not
exist" test in WorkflowExecutor.SaveLogs is too weak because iterating over
we.errors does not assert that any errors were recorded. Update the test to
explicitly assert that we.errors is empty after calling SaveLogs, while keeping
the existing fs.ErrNotExist check for any unexpected entries, so the invariant
is enforced by the test itself.

In `@workflow/executor/executor.go`:
- Around line 748-759: When `archiveSystem` is enabled in `we.saveContainerLogs`
handling, the `fs.ErrNotExist` branch for `common.InitContainerName` and
`common.WaitContainerName` currently skips artifacts silently; add a debug-level
log in this branch so skipped system container logs are traceable without
changing behavior. Use the existing `archiveSystem` loop in `executor.go` and
the `saveContainerLogs` call site to include the container name and that the
logs were not found.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37e77fc7-d34a-4b4d-a27b-6d1698cbf4d4

📥 Commits

Reviewing files that changed from the base of the PR and between 7fefac7 and e56e40c.

⛔ Files ignored due to path filters (9)
  • api/openapi-spec/swagger.json is excluded by !**/api/openapi-spec/*.json
  • pkg/apis/workflow/v1alpha1/generated.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
  • pkg/apis/workflow/v1alpha1/openapi_generated.go is excluded by !**/*_generated.go
  • pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go is excluded by !**/zz_generated.*.go
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md is excluded by !**/sdks/java/client/**
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1WorkflowSpec.md is excluded by !**/sdks/java/client/**
📒 Files selected for processing (38)
  • .features/pending/archive-system-container-logs.md
  • api/jsonschema/schema.json
  • cmd/argoexec/commands/init.go
  • cmd/argoexec/commands/logs.go
  • cmd/argoexec/commands/logs_test.go
  • cmd/argoexec/commands/wait.go
  • docs/configure-archive-logs.md
  • docs/executor_swagger.md
  • docs/fields.md
  • manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
  • manifests/base/crds/full/argoproj.io_cronworkflows.yaml
  • manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml
  • manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/full/argoproj.io_workflows.yaml
  • manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/full/argoproj.io_workflowtasksets.yaml
  • manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml
  • manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtasksets.yaml
  • manifests/quick-start-minimal.yaml
  • manifests/quick-start-mysql.yaml
  • manifests/quick-start-postgres.yaml
  • manifests/quick-start-telemetry.yaml
  • pkg/apis/workflow/v1alpha1/artifact_repository_types.go
  • pkg/apis/workflow/v1alpha1/generated.proto
  • pkg/apis/workflow/v1alpha1/workflow_types.go
  • pkg/plugins/executor/swagger.yml
  • test/e2e/functional_test.go
  • test/e2e/testdata/workflow-archive-init-fail.yaml
  • test/e2e/testdata/workflow-archive-init-wait-logs.yaml
  • ui/src/shared/services/workflows-service.ts
  • util/logging/slog.go
  • workflow/controller/workflowpod.go
  • workflow/executor/executor.go
  • workflow/executor/executor_test.go
  • workflow/util/merge.go

- log a debug message when a system container's combined log file is missing and archiving is skipped
- strengthen TestSaveLogs to assert exactly one error is recorded
- remove double close in Test_teeContainerLogs

Signed-off-by: myzk-a <rorosocksxion@gmail.com>
@myzk-a

myzk-a commented Jul 5, 2026

Copy link
Copy Markdown
Author

Addressed nitpicks #2#4 in 284defa. Two notes:

  • 3: adopted the diagnosis, but require.Empty would fail — main legitimately records one unconfigured-storage error here. Used require.Len(t, we.errors, 1) + assert.EqualError instead.
  • 1: deliberately not adopted. Asserting init-logs absence would pass even if archiving were broken, and would freeze a documented limitation into a test contract. The limitation is documented in docs/configure-archive-logs.md.

myzk-a added 5 commits July 7, 2026 00:52
Resolve conflicts from the init-less pod layout PR (argoproj#16161) and adapt system
container log archiving to init-less mode:
- SaveLogs derives the system container set from pod topology (supervisor in
  init-less, init/wait otherwise)
- move the log tee into runAuxiliaryContainer so both wait and supervisor
  capture their own logs

Signed-off-by: myzk-a <rorosocksxion@gmail.com>
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
… sample

Signed-off-by: myzk-a <rorosocksxion@gmail.com>
…-container-logs

Signed-off-by: myzk-a <rorosocksxion@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
workflow/controller/workflowpod.go (1)

1553-1575: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include system-log archiving when deciding whether to add the aux container. Resource/data templates still skip the wait/supervisor container when only ArchiveSystemContainerLogs is enabled, because needsAuxCtr is driven by SaveLogsAsArtifact() only. That leaves nothing to collect the system logs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@workflow/controller/workflowpod.go` around lines 1553 - 1575, Update the
aux-container decision path, specifically the logic driven by needsAuxCtr and
SaveLogsAsArtifact(), to also require the aux container when
IsArchiveSystemContainerLogs(tmpl) is enabled. Preserve the existing behavior
for regular log archiving and ensure resource/data templates retain the
wait/supervisor container for system-log collection.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@workflow/controller/workflowpod.go`:
- Around line 1553-1575: Update the aux-container decision path, specifically
the logic driven by needsAuxCtr and SaveLogsAsArtifact(), to also require the
aux container when IsArchiveSystemContainerLogs(tmpl) is enabled. Preserve the
existing behavior for regular log archiving and ensure resource/data templates
retain the wait/supervisor container for system-log collection.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8e0cdba8-9650-4294-9b5c-a6b862c7e3b9

📥 Commits

Reviewing files that changed from the base of the PR and between 18305f6 and e1f87b5.

⛔ Files ignored due to path filters (3)
  • api/openapi-spec/swagger.json is excluded by !**/api/openapi-spec/*.json
  • pkg/apis/workflow/v1alpha1/generated.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
  • pkg/apis/workflow/v1alpha1/openapi_generated.go is excluded by !**/*_generated.go
📒 Files selected for processing (24)
  • api/jsonschema/schema.json
  • docs/executor_swagger.md
  • docs/fields.md
  • docs/workflow-controller-configmap.yaml
  • manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
  • manifests/base/crds/full/argoproj.io_cronworkflows.yaml
  • manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml
  • manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/full/argoproj.io_workflows.yaml
  • manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/full/argoproj.io_workflowtasksets.yaml
  • manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml
  • manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtasksets.yaml
  • manifests/quick-start-minimal.yaml
  • manifests/quick-start-mysql.yaml
  • manifests/quick-start-postgres.yaml
  • manifests/quick-start-telemetry.yaml
  • pkg/apis/workflow/v1alpha1/generated.proto
  • pkg/apis/workflow/v1alpha1/workflow_types.go
  • pkg/plugins/executor/swagger.yml
  • workflow/controller/workflowpod.go
🚧 Files skipped from review as they are similar to previous changes (20)
  • docs/workflow-controller-configmap.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml
  • manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml
  • manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml
  • pkg/apis/workflow/v1alpha1/generated.proto
  • manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml
  • pkg/apis/workflow/v1alpha1/workflow_types.go
  • manifests/quick-start-minimal.yaml
  • manifests/quick-start-mysql.yaml
  • docs/fields.md
  • api/jsonschema/schema.json
  • manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
  • manifests/base/crds/minimal/argoproj.io_workflowtasksets.yaml
  • manifests/base/crds/full/argoproj.io_cronworkflows.yaml
  • manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml
  • manifests/base/crds/full/argoproj.io_workflowtasksets.yaml
  • docs/executor_swagger.md
  • manifests/base/crds/full/argoproj.io_workflows.yaml
  • manifests/quick-start-postgres.yaml

myzk-a added 2 commits July 14, 2026 03:11
Signed-off-by: myzk-a <rorosocksxion@gmail.com>
…iveSystemContainerLogs is set.

Signed-off-by: myzk-a <rorosocksxion@gmail.com>
@myzk-a

myzk-a commented Jul 14, 2026

Copy link
Copy Markdown
Author

Good catch on the resource templates — fixed in 35fc008: needsAuxCtr now also
considers SaveSystemContainerLogsAsArtifact(), with unit tests for both the legacy
(wait) and init-less (supervisor) layouts.

Data templates are intentionally unchanged: they never get an aux container even with
archiveLogs enabled, because argoexec runs as the main container there (see the
comment above needsAuxCtr). Changing that would alter pre-existing behavior beyond
the scope of this PR.

Comment thread docs/configure-archive-logs.md Outdated

## Archiving Init and Wait Container Logs

By default, only the `main` container's logs are archived. Every Workflow Pod also runs Argo's own

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get one sentence per line please as per the docs guidelines? Just makes it much easier to diff in future. Thanks

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review, and for the pointer to the docs guidelines! Fixed in e5af2df — reformatted the whole section to one sentence per line.

Signed-off-by: myzk-a <rorosocksxion@gmail.com>
@myzk-a

myzk-a commented Jul 14, 2026

Copy link
Copy Markdown
Author

Since #16161 (init-less pod layout) was merged, I've merged main and extended this PR so archiveSystemContainerLogs works under both pod layouts: the legacy layout archives init-logs / wait-logs, and the init-less layout archives a single supervisor-logs — notably still capturing it when input artifact loading fails, which the legacy layout cannot. The init-less delta is small: a container-name switch in SaveLogs plus moving the tee into the shared runAuxiliaryContainer. If you'd prefer the init-less support split into a follow-up PR to keep review scope down, happy to do that. The PR description has been updated accordingly.

@myzk-a

myzk-a commented Jul 14, 2026

Copy link
Copy Markdown
Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/configure-archive-logs.md`:
- Line 71: Update the documentation sentence to hyphenate “garbage-collected”
when it modifies “Pods,” changing “garbage collected Pods” to “garbage-collected
Pods.”
- Line 68: Update the sentence describing Argo system containers to scope it to
legacy Workflow Pod layouts rather than every Workflow Pod, while preserving the
existing explanation of the init and wait containers and their log-archiving
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c2a68a99-cdc0-418e-8455-baa65dca6537

📥 Commits

Reviewing files that changed from the base of the PR and between e1f87b5 and e5af2df.

📒 Files selected for processing (4)
  • docs/configure-archive-logs.md
  • test/e2e/functional_test.go
  • workflow/controller/workflowpod.go
  • workflow/controller/workflowpod_initless_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • workflow/controller/workflowpod_initless_test.go
  • test/e2e/functional_test.go
  • workflow/controller/workflowpod.go

Comment thread docs/configure-archive-logs.md Outdated
Comment thread docs/configure-archive-logs.md Outdated
Signed-off-by: myzk-a <rorosocksxion@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
workflow/controller/workflowpod_build_test.go (1)

43-84: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add archiveSystemContainerLogs to the stub and test the new feature.

Since this PR introduces archiveSystemContainerLogs and modifies the needsAuxCtr logic to consider it, the stubPodBuilderDeps should support toggling this flag to allow pure testing of the new controller logic. Currently, IsArchiveSystemContainerLogs hardcodes false on the stub.

Consider adding an archiveSystemContainerLogs bool field to stubPodBuilderDeps and returning it in IsArchiveSystemContainerLogs.
Do you want me to generate a test case that verifies archiveSystemContainerLogs = true correctly schedules an auxiliary container (e.g., supervisor) for a resource template, similar to how TestBuild_InitlessResourceManifestFrom_SchedulesSupervisor is implemented?

♻️ Proposed refactor for the stub
 type stubPodBuilderDeps struct {
 	executorImage              string
 	archiveLogs                bool
+	archiveSystemContainerLogs bool
 	initContainerName          string // name of the init container legacyLayout asks for
 
 	// gotTimeoutNow records the now value build threads into checkTemplateTimeouts,
@@ -80,5 +81,5 @@
 }
 
 func (s *stubPodBuilderDeps) IsArchiveLogs(_ *wfv1.Template) bool                { return s.archiveLogs }
-func (s *stubPodBuilderDeps) IsArchiveSystemContainerLogs(_ *wfv1.Template) bool { return false }
+func (s *stubPodBuilderDeps) IsArchiveSystemContainerLogs(_ *wfv1.Template) bool { return s.archiveSystemContainerLogs }
 func (s *stubPodBuilderDeps) executorServiceAccountName(_ *wfv1.Template) string { return "" }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@workflow/controller/workflowpod_build_test.go` around lines 43 - 84, Extend
stubPodBuilderDeps with an archiveSystemContainerLogs bool field and update
IsArchiveSystemContainerLogs to return that field instead of hardcoding false.
Add a focused test covering archiveSystemContainerLogs=true for a resource
template, asserting that build schedules the auxiliary supervisor container,
following the pattern of
TestBuild_InitlessResourceManifestFrom_SchedulesSupervisor.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml`:
- Around line 969-972: Update every archiveSystemContainerLogs schema
description identified in the comment to describe both supported Pod layouts:
use “system-container logs,” explicitly mention init/wait containers for Pods
with init containers, and supervisor logs for init-less Pods. Keep the field
name and boolean schema unchanged across all occurrences.

In `@manifests/base/crds/full/argoproj.io_cronworkflows.yaml`:
- Around line 1059-1062: Update the API comment for archiveSystemContainerLogs
in the workflow types definition to document that supervisor logs are also
archived for init-less Pods, alongside init/wait container logs. Regenerate all
affected CRD manifests so every generated description reflects the complete
behavior.

In `@manifests/base/crds/full/argoproj.io_workflows.yaml`:
- Around line 982-985: Update every generated CRD description for
archiveSystemContainerLogs to describe archiving system-container logs,
explicitly covering legacy init/wait containers and init-less supervisor
containers. Apply the wording consistently across all occurrences in the
manifest.

In `@manifests/base/crds/full/argoproj.io_workflowtemplates.yaml`:
- Around line 967-970: The archiveSystemContainerLogs descriptions currently
mention only init/wait containers; update the descriptions at
manifests/base/crds/full/argoproj.io_workflowtemplates.yaml lines 967-970,
1013-1016, 3949-3952, 18168-18171, 22382-22386, 23730-23734, 25267-25270,
28073-28076, 29482-29485, 30784-30787, 35342-35346, and 36668-36672 to also
document supervisor logs for init-less Pods, using layout-neutral wording
consistently.

In `@manifests/quick-start-postgres.yaml`:
- Around line 969-972: Update the source comment for archiveSystemContainerLogs
to mention supervisor alongside init/wait containers, then regenerate the
manifests so the generated schema descriptions reflect that init-less Pods also
archive supervisor logs.

---

Nitpick comments:
In `@workflow/controller/workflowpod_build_test.go`:
- Around line 43-84: Extend stubPodBuilderDeps with an
archiveSystemContainerLogs bool field and update IsArchiveSystemContainerLogs to
return that field instead of hardcoding false. Add a focused test covering
archiveSystemContainerLogs=true for a resource template, asserting that build
schedules the auxiliary supervisor container, following the pattern of
TestBuild_InitlessResourceManifestFrom_SchedulesSupervisor.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f027fa26-ff5d-4ddf-979d-c486d294903d

📥 Commits

Reviewing files that changed from the base of the PR and between 5345fc1 and 7c6cb21.

⛔ Files ignored due to path filters (5)
  • api/openapi-spec/swagger.json is excluded by !**/api/openapi-spec/*.json
  • pkg/apis/workflow/v1alpha1/generated.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
  • pkg/apis/workflow/v1alpha1/openapi_generated.go is excluded by !**/*_generated.go
  • pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go is excluded by !**/zz_generated.*.go
  • sdks/java/client/docs/IoArgoprojWorkflowV1alpha1WorkflowSpec.md is excluded by !**/sdks/java/client/**
📒 Files selected for processing (16)
  • api/jsonschema/schema.json
  • docs/fields.md
  • manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
  • manifests/base/crds/full/argoproj.io_cronworkflows.yaml
  • manifests/base/crds/full/argoproj.io_workflows.yaml
  • manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
  • manifests/quick-start-minimal.yaml
  • manifests/quick-start-mysql.yaml
  • manifests/quick-start-postgres.yaml
  • manifests/quick-start-telemetry.yaml
  • pkg/apis/workflow/v1alpha1/generated.proto
  • pkg/apis/workflow/v1alpha1/workflow_types.go
  • workflow/controller/workflowpod.go
  • workflow/controller/workflowpod_build_test.go
  • workflow/controller/workflowpod_initless_test.go
  • workflow/util/merge.go
🚧 Files skipped from review as they are similar to previous changes (10)
  • workflow/util/merge.go
  • pkg/apis/workflow/v1alpha1/workflow_types.go
  • pkg/apis/workflow/v1alpha1/generated.proto
  • api/jsonschema/schema.json
  • workflow/controller/workflowpod.go
  • manifests/quick-start-minimal.yaml
  • manifests/quick-start-mysql.yaml
  • docs/fields.md
  • workflow/controller/workflowpod_initless_test.go
  • manifests/quick-start-telemetry.yaml

Comment thread manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml
Comment thread manifests/base/crds/full/argoproj.io_cronworkflows.yaml
Comment thread manifests/base/crds/full/argoproj.io_workflows.yaml
Comment thread manifests/base/crds/full/argoproj.io_workflowtemplates.yaml
Comment thread manifests/quick-start-postgres.yaml
myzk-a added 2 commits July 17, 2026 00:54
…scriptions.

Signed-off-by: myzk-a <rorosocksxion@gmail.com>
… tests.

Signed-off-by: myzk-a <rorosocksxion@gmail.com>
@myzk-a

myzk-a commented Jul 17, 2026

Copy link
Copy Markdown
Author

Add archiveSystemContainerLogs to the stub and test the new feature.

Done in 7c47be2 — added the toggle to stubPodBuilderDeps and positive tests for both layouts (TestBuild_InitlessResourceSystemLogsOnly_SchedulesSupervisor / TestBuild_LegacyResourceSystemLogsOnly_SchedulesWaitContainer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Archive Logs for init and wait container

2 participants