Skip to content

feat: re-land graceful scale-down for AlluxioRuntime with e2e test#6061

Open
jakharmonika364 wants to merge 13 commits into
fluid-cloudnative:masterfrom
jakharmonika364:feat-alluxio-scaledown-e2e
Open

feat: re-land graceful scale-down for AlluxioRuntime with e2e test#6061
jakharmonika364 wants to merge 13 commits into
fluid-cloudnative:masterfrom
jakharmonika364:feat-alluxio-scaledown-e2e

Conversation

@jakharmonika364

Copy link
Copy Markdown
Contributor

Re-lands #5805, reverted in #6059 because it had no e2e coverage of the actual scale-down -> drain -> decommission -> data-integrity path.

This PR adds that e2e test under test/gha-e2e/alluxio-scaledown/: binds a 2-replica AlluxioRuntime, reads data, scales down to 1 replica, waits for the worker StatefulSet to actually converge, then reads again.

While wiring this up I found GracefulWorkerScaleDown was registered as a feature gate but never exposed as a flag on the alluxioruntime-controller binary (cmd/alluxio/app/alluxio.go), unlike csi and fluidapp, so it was unreachable in any real deployment. Fixed that too - the e2e test enables it via a deployment patch since there's no Helm value for it yet.

Original feature code is unchanged from #5805.

@fluid-e2e-bot

fluid-e2e-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign yangyuliufeng for approval by writing /assign @yangyuliufeng in a comment. For more information see:The Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@fluid-e2e-bot

fluid-e2e-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

Hi @jakharmonika364. Thanks for your PR.

I'm waiting for a fluid-cloudnative member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a new end-to-end test suite for testing the graceful scale-down of AlluxioRuntime, including the test script and associated Kubernetes resource manifests. It also exposes the feature gate flags in the Alluxio controller command. The review feedback highlights a critical missing blank import required to register the feature gates, and suggests improvements to the E2E test script, such as simplifying the wait-loop logging logic and properly scoping variables as local to prevent global namespace pollution.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread cmd/alluxio/app/alluxio.go Outdated
Comment thread test/gha-e2e/alluxio-scaledown/test.sh
Comment thread test/gha-e2e/alluxio-scaledown/test.sh
@jakharmonika364

Copy link
Copy Markdown
Contributor Author

Fixed the wait_dataset_bound and wait_job_completed issues. The blank import suggestion isn't needed though - pkg/ddc/alluxio already imports pkg/features directly (replicas.go), and cmd/alluxio/app/alluxio.go imports pkg/ddc/alluxio, so the init() already runs. Verified --feature-gates works via go run ./cmd/alluxio start --help.

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.44978% with 15 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (master@676f47a). Learn more about missing BASE report.

Files with missing lines Patch % Lines
pkg/ddc/alluxio/replicas.go 92.21% 9 Missing and 4 partials ⚠️
pkg/features/features.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             master    #6061   +/-   ##
=========================================
  Coverage          ?   64.97%           
=========================================
  Files             ?      487           
  Lines             ?    34216           
  Branches          ?        0           
=========================================
  Hits              ?    22233           
  Misses            ?    10246           
  Partials          ?     1737           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI 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.

Pull request overview

Re-lands the AlluxioRuntime graceful worker scale-down feature by adding a new Kind-based GitHub Actions e2e scenario and exposing the --feature-gates flag on the alluxioruntime-controller binary so the gate can be enabled in real deployments.

Changes:

  • Add a new test/gha-e2e/alluxio-scaledown/ e2e scenario that scales an AlluxioRuntime from 2→1 and verifies data access before/after.
  • Expose feature gates on alluxioruntime-controller via DefaultMutableFeatureGate.AddFlag(...).
  • Wire the new e2e scenario into .github/scripts/gha-e2e.sh so it runs in CI.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/gha-e2e/alluxio-scaledown/test.sh New e2e driver script that enables the gate, creates runtime, scales down, and re-reads data
test/gha-e2e/alluxio-scaledown/read_before_job.yaml Job used to validate data access before scale-down
test/gha-e2e/alluxio-scaledown/read_after_job.yaml Job used to validate data access after scale-down
test/gha-e2e/alluxio-scaledown/dataset.yaml Dataset + 2-replica AlluxioRuntime manifest for the scale-down scenario
cmd/alluxio/app/alluxio.go Adds --feature-gates flag exposure for the alluxio controller binary
.github/scripts/gha-e2e.sh Runs the new alluxio scale-down e2e scenario in the CI e2e sequence

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/gha-e2e/alluxio-scaledown/test.sh Outdated
Comment thread test/gha-e2e/alluxio-scaledown/test.sh Outdated
Comment thread test/gha-e2e/alluxio-scaledown/test.sh
Comment thread test/gha-e2e/alluxio-scaledown/read_after_job.yaml Outdated
Comment thread test/gha-e2e/alluxio-scaledown/dataset.yaml Outdated
Comment thread test/gha-e2e/alluxio-scaledown/test.sh Outdated
Comment thread test/gha-e2e/alluxio-scaledown/test.sh
Comment thread test/gha-e2e/alluxio-scaledown/test.sh Outdated
Comment thread test/gha-e2e/alluxio-scaledown/dataset.yaml Outdated
@jakharmonika364 jakharmonika364 force-pushed the feat-alluxio-scaledown-e2e branch from c3028aa to af5935d Compare June 25, 2026 10:23
@jakharmonika364

Copy link
Copy Markdown
Contributor Author

Found why CI was failing: this branch forked from master before #6059's revert merged, so the PR's merge-ref was silently dropping the whole feature (pkg/features, replicas.go logic, etc.) since my commits never touched those files directly. Rebuilt the branch off current master with the revert reverted, then replayed the e2e/flag-fix commits on top - --feature-gates=GracefulWorkerScaleDown=true now actually registers.

Comment thread test/gha-e2e/alluxio-scaledown/minio_create_bucket.yaml Fixed
- mountPoint: s3://scaledown/
name: scaledown
options:
alluxio.underfs.s3.endpoint: "http://scaledown-minio:9000"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Leaving this as http - it's an in-cluster only MinIO with throwaway test creds, same as curvine's existing endpoint_url: http://minio:9000 fixture. No real traffic to protect here.

@jakharmonika364

Copy link
Copy Markdown
Contributor Author

@cheyang can you please review this once

@cheyang

cheyang commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Hey @jakharmonika364 — this PR has picked up merge conflicts since the last review round (likely from recent master changes). Could you rebase on top of the latest master and force-push? The code itself looks good and was ready to merge on the last pass, so once the conflicts are resolved we can move forward quickly.

git fetch upstream master
git rebase upstream/master
# resolve any conflicts
git push --force-with-lease

@jakharmonika364 jakharmonika364 force-pushed the feat-alluxio-scaledown-e2e branch from e8c3871 to d8fa056 Compare July 6, 2026 04:53
@jakharmonika364

Copy link
Copy Markdown
Contributor Author

Done - rebased on top of upstream/master and resolved the merge conflict in cmd/alluxio/app/alluxio.go (a duplicate import block that had already landed on master separately). Force-pushed with --force-with-lease. The PR now shows as mergeable, ready for another look @cheyang

@cheyang

cheyang commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

/copilot review

@cheyang

cheyang commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

@gemini-code-assist /review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a graceful worker scale-down feature (GracefulWorkerScaleDown) for AlluxioRuntime to decommission workers before they are terminated, allowing the master to migrate cached blocks. It includes decommissioning operations, replica synchronization logic, a new feature gate, and E2E tests. The review feedback highlights three key improvement opportunities: skipping decommissioning for pending worker pods that lack a HostIP to prevent blocking the scale-down process, avoiding redundant decommissioning executions across reconciles by checking if the process is already tracked, and removing a redundant status update call to prevent unnecessary API overhead.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread pkg/ddc/alluxio/replicas.go Outdated
Comment thread pkg/ddc/alluxio/replicas.go Outdated
Comment thread pkg/ddc/alluxio/replicas.go
@jakharmonika364 jakharmonika364 force-pushed the feat-alluxio-scaledown-e2e branch from 7d70787 to 19d47c1 Compare July 6, 2026 05:46
@cheyang

cheyang commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

/copilot review

Copilot AI 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.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Comment thread test/gha-e2e/alluxio-scaledown/test.sh
@cheyang

cheyang commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Requesting changes. The graceful scale-down flow is well structured and the test coverage is solid, but two things block merge as-is.

The bigger one is cross-cutting: the drain path depends on alluxio fsadmin decommissionWorker, which only exists on Alluxio >= 2.9. The GracefulWorkerScaleDown gate doesn't know what Alluxio version the master runs, so enabling it against an older image turns every scale-in into a stuck reconcile that only clears at the 10m forced-proceed deadline. This needs to version-gate or runtime-detect the capability and degrade gracefully on older versions.

The second is that the decommission command's result is trusted too readily — stdout/stderr are dropped and success is taken from a nil error alone, so partial failures reported in the output (or an unsupported subcommand) can be read as "drain launched." Please inspect the command output/exit code and handle partial failures. Details inline.

Comment thread pkg/ddc/alluxio/operations/decommission.go
Comment thread pkg/ddc/alluxio/operations/decommission.go Outdated

@cheyang cheyang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Requesting changes. Two blocking items, both detailed in inline comments on pkg/ddc/alluxio/operations/decommission.go:

  1. Hard dependency on Alluxio >= 2.9. The drain path calls alluxio fsadmin decommissionWorker, which doesn't exist on older masters. The GracefulWorkerScaleDown gate doesn't know the master's Alluxio version, so enabling it against a pre-2.9 image turns every scale-in into a stuck reconcile that only clears at the 10m forced-proceed deadline. Please version-gate or runtime-detect the capability and degrade gracefully on older versions.

  2. The decommission command result is assumed successful. stdout/stderr are discarded and success is taken from a nil error alone, so partial failures reported in the command output (or an unsupported subcommand) can be read as "drain launched." Please inspect the command output/exit code and handle partial failures; the same care applies to the fixed-layout parsing in CountActiveWorkers/parseActiveWorkerCount.

Happy to re-review once these are addressed.

jakharmonika364 added a commit to jakharmonika364/fluid that referenced this pull request Jul 11, 2026
…mission output

Addresses cheyang's review on fluid-cloudnative#6061 (two blocking items) plus a Copilot
suggestion on the feature-gates patch in test.sh.

1. Old Alluxio masters (< 2.9, where "fsadmin decommissionWorker" does
   not exist) previously caused SyncReplicas to stall forever, not just
   until the 10m deadline as it looked at first glance: returning
   drainErr immediately bypassed the deadline-tracking logic entirely,
   since decommissionStart is only ever persisted inside the "not
   drained" branch. A drain error is now routed through the same
   deadline-bounded path as "not yet drained", so it's retried and
   logged at Error level (visible immediately, not masked as the
   routine errWorkersNotYetDrained) and, past the deadline, the engine
   degrades to an ungraceful scale-down instead of hanging - the same
   fallback the codebase already accepts for a stuck/unhealthy drain.

2. DecommissionWorkers now captures stdout/stderr (previously
   discarded) and does a best-effort scan of stdout for failure
   indicators, since decommissionWorker can report a per-worker problem
   while still exiting 0. stderr is deliberately not scanned - Alluxio's
   CLI is a JVM process that can print benign warnings to stderr on a
   successful run, matching how every other command wrapper in this
   package already only inspects stderr once err != nil. The real
   verification remains CountActiveWorkers on subsequent reconciles; a
   false positive here just costs one extra bounded retry.

3. parseActiveWorkerCount now returns an error instead of silently
   returning 0 when the "Worker Name" header is missing from the
   capacity report. A report this caller can't recognize must not be
   misread as "every worker has drained", since that's exactly the
   signal the engine acts on to let a scale-down proceed.

4. test.sh's enable_graceful_scale_down now merges into an existing
   --feature-gates arg via jq instead of always appending a new one,
   which would silently override it (last-flag-wins string flag) and
   disable whatever gates Helm values had already set.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
@jakharmonika364

Copy link
Copy Markdown
Contributor Author

@cheyang I addressed both in 0707c4a - replied inline with details on each. Also merged the Copilot suggestion on the feature-gates patch in test.sh. Let me know if the deadline-bounded degrade approach for old Alluxio versions works for you, or if you'd rather I implement explicit version detection instead.

Requesting changes. Two blocking items, both detailed in inline comments on pkg/ddc/alluxio/operations/decommission.go:

  1. Hard dependency on Alluxio >= 2.9. The drain path calls alluxio fsadmin decommissionWorker, which doesn't exist on older masters. The GracefulWorkerScaleDown gate doesn't know the master's Alluxio version, so enabling it against a pre-2.9 image turns every scale-in into a stuck reconcile that only clears at the 10m forced-proceed deadline. Please version-gate or runtime-detect the capability and degrade gracefully on older versions.
  2. The decommission command result is assumed successful. stdout/stderr are discarded and success is taken from a nil error alone, so partial failures reported in the command output (or an unsupported subcommand) can be read as "drain launched." Please inspect the command output/exit code and handle partial failures; the same care applies to the fixed-layout parsing in CountActiveWorkers/parseActiveWorkerCount.

Happy to re-review once these are addressed.

@jakharmonika364 jakharmonika364 requested a review from cheyang July 11, 2026 06:07
@cheyang

cheyang commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

/copilot review

@cheyang

cheyang commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

@gemini-code-assist /review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a graceful worker scale-down feature for the Alluxio runtime, allowing targeted workers to be decommissioned and their cached blocks migrated before pod termination. It adds decommissioning CLI wrappers, integrates them into the replica synchronization logic with a 10-minute deadline fallback, and includes comprehensive unit and E2E tests. The review feedback highlights a critical issue where transient failures during the initial decommission command could prevent subsequent retries because the decommissioning state is immediately marked as tracked. It is recommended to record the success or failure of the decommission command in the runtime condition's reason to ensure robust retries.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread pkg/ddc/alluxio/replicas.go Outdated
Comment thread pkg/ddc/alluxio/replicas.go
@cheyang

cheyang commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Re-review at f97dbd5 — both blocking items from the last round look addressed.

Alluxio version dependency (blocker A): SyncReplicas no longer short-circuits on drainErr. A drain failure (including the decommissionWorker subcommand not existing on Alluxio < 2.9) is now routed through the same deadline-bounded branch as !drained, so the engine still tracks decommissionStart, logs the real error at Error level on every reconcile, and after defaultWorkerDecommissionDeadline degrades to an ungraceful scale-down rather than stalling forever. That matches the fallback the codebase already accepts for a stuck/unhealthy drain. The two new Ginkgo cases in pkg/ddc/alluxio/replicas_drain_test.go ("DecommissionWorkers itself fails") exercise both the tracking-marker path and the past-deadline force-through, so the version-compat behavior is pinned by tests.

Exec result handling (blocker B): DecommissionWorkers now captures stdout/stderr and does a best-effort scan of stdout for fail/unrecognized before returning success, so an exit-0-with-per-worker-error case is no longer silently accepted. stderr is intentionally not treated as failure — the rest of the package already only inspects stderr once err != nil, and Alluxio's JVM CLI prints benign warnings there. parseActiveWorkerCount now returns an error instead of a silent 0 when the Worker Name header is missing, which was the real hazard: a report the caller can't recognize must not be misread as "every worker drained." Unit tests cover both the stdout-failure and unrecognized-report paths.

Secondary changes on top of the fixes look sensible: enable_graceful_scale_down in test.sh now merges into an existing --feature-gates= arg via jq instead of appending a second last-flag-wins occurrence; minio images are pinned to explicit RELEASE.* tags to remove any residual :latest drift from the archived Docker Hub repo; and wait_job_completed retries pod logs with --previous to survive the job controller terminating the pod ahead of our kubectl logs call.

One prior Copilot note ("the e2e doesn't assert decommissioning actually ran") is already answered in the source: the added comment above main() in test.sh explains that a single-node Kind cluster dedupes decommission addresses by HostIP, so the e2e can only assert convergence + data survival, and per-address targeting is covered by the gomonkey unit tests in replicas_drain_test.go. That's a reasonable split.

CI is green across the matrix (kind-e2e + backward-compat on v1.22.17 / v1.24.17 / v1.28.15 / v1.30.13 / v1.33.2, plus CodeQL, staticcheck, lint, unittest, Sonar, DCO). No new blocking issues from my side — from a code-review standpoint this is ready. Remaining gate is on the maintainer to remove needs-ok-to-test and add /lgtm + /approve.

…dvancedStatefulSet (fluid-cloudnative#4193) (fluid-cloudnative#5805)" (fluid-cloudnative#6059)

This reverts commit 333e13a.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
Adds a real-cluster scenario exercising the scale-down -> drain ->
decommission -> data-integrity path: bind a 2-replica AlluxioRuntime,
read data, scale down to 1 replica, wait for the worker StatefulSet to
actually converge (proving the drain doesn't stall), then read again.

Also wires --feature-gates into the alluxioruntime-controller binary
(cmd/alluxio/app/alluxio.go), mirroring cmd/csi and cmd/fluidapp -
without it GracefulWorkerScaleDown was registered but unreachable on a
real deployment, so the e2e test enables it via a deployment patch.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
Simplify wait_dataset_bound's elapsed-time tracking to a single
counter (matches wait_worker_replicas), and declare succeed/job_failed
as local in wait_job_completed to avoid polluting global scope.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
- check kubectl patch exit codes instead of letting failures surface
  as confusing downstream timeouts
- log the WorkerDecommissioning condition while polling so a stuck
  drain is debuggable from CI output
- replace the external apache.org mirror mount with an in-cluster
  MinIO bucket seeded with one known object, and assert its exact
  content before/after scale-down instead of just checking the
  directory is non-empty - the previous assertion would pass even if
  decommission silently dropped cached data instead of migrating it

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
Alluxio mounts s3://scaledown/ at /scaledown inside its namespace
(named after the Dataset mount's name), not at the FUSE root. The
existing alluxio test never noticed this because its assertion just
checks "ls /data" is non-empty, which passes either way. Use the
correct /data/scaledown/fixture.txt path so the content check
actually exercises the fixture.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
…ommission logic

- test.sh: wait for the scaledown-minio deployment rollout before creating
  the bucket-create job; without it the job could exhaust its retries
  before minio finished starting, causing a flaky e2e failure on some
  Kubernetes versions.
- replicas.go: skip (instead of aborting the whole batch) a scale-down
  target pod that hasn't been assigned a host IP yet, so sibling workers
  that are ready still get decommissioned this reconcile.
- replicas.go: avoid re-issuing the (exec-heavy) decommissionWorker call on
  every reconcile once a decommission attempt is already tracked; only
  poll the active worker count until the drain completes.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
Without a readinessProbe, "kubectl rollout status" marks the minio
deployment ready as soon as the container starts, not once minio is
actually listening - so the earlier rollout-status wait didn't fully
close the race with the bucket-create job. Add an httpGet probe against
minio's own /minio/health/ready endpoint so rollout status genuinely
waits for the server to be reachable.

Also dump the bucket-create job's pod logs to the test output before
panicking on failure, since previously a failure gave no signal at all
about what mc actually hit.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
… wait

alluxio fsadmin decommissionWorker addresses workers by their web port
(default 30000), not the RPC port (29999) used elsewhere - it monitors
the worker's workload as exposed on the web server. Rename
defaultWorkerRPCPort/getWorkerRPCPort (unused for anything else) to
their web-port equivalents and fix the address construction in
drainScalingDownWorkers accordingly.

Also pass --wait 0s to decommissionWorker: it defaults to 5m, which
would otherwise block the exec call - and therefore the engine's
reconcile loop - waiting for the worker to idle. The engine already
polls CountActiveWorkers across reconciles, so the command only needs
to initiate the decommission and return immediately.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
…diagnostics

A pod gets a HostIP as soon as it's scheduled, well before its
containers actually start (Pending/ContainerCreating), so HostIP alone
doesn't mean the Alluxio worker process is up and listening on the web
port. Also require pod.Status.Phase == Running before targeting a pod
for decommission, consistent with the existing skip-and-continue
behavior for not-yet-ready pods. Updated the test fixtures accordingly.

Also harden the bucket-create job diagnostics in test.sh: addressing a
job by "job/$name" makes kubectl logs resolve the newest pod and can
itself hang waiting for that pod to reach Running (as seen in a recent
CI run, where it timed out and gave no signal). List the job's pods by
label selector, describe each, and fetch logs by pod name with
--request-timeout so a stuck pod can't block the diagnostics anymore.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
…mission output

Addresses cheyang's review on fluid-cloudnative#6061 (two blocking items) plus a Copilot
suggestion on the feature-gates patch in test.sh.

1. Old Alluxio masters (< 2.9, where "fsadmin decommissionWorker" does
   not exist) previously caused SyncReplicas to stall forever, not just
   until the 10m deadline as it looked at first glance: returning
   drainErr immediately bypassed the deadline-tracking logic entirely,
   since decommissionStart is only ever persisted inside the "not
   drained" branch. A drain error is now routed through the same
   deadline-bounded path as "not yet drained", so it's retried and
   logged at Error level (visible immediately, not masked as the
   routine errWorkersNotYetDrained) and, past the deadline, the engine
   degrades to an ungraceful scale-down instead of hanging - the same
   fallback the codebase already accepts for a stuck/unhealthy drain.

2. DecommissionWorkers now captures stdout/stderr (previously
   discarded) and does a best-effort scan of stdout for failure
   indicators, since decommissionWorker can report a per-worker problem
   while still exiting 0. stderr is deliberately not scanned - Alluxio's
   CLI is a JVM process that can print benign warnings to stderr on a
   successful run, matching how every other command wrapper in this
   package already only inspects stderr once err != nil. The real
   verification remains CountActiveWorkers on subsequent reconciles; a
   false positive here just costs one extra bounded retry.

3. parseActiveWorkerCount now returns an error instead of silently
   returning 0 when the "Worker Name" header is missing from the
   capacity report. A report this caller can't recognize must not be
   misread as "every worker has drained", since that's exactly the
   signal the engine acts on to let a scale-down proceed.

4. test.sh's enable_graceful_scale_down now merges into an existing
   --feature-gates arg via jq instead of always appending a new one,
   which would silently override it (last-flag-wins string flag) and
   disable whatever gates Helm values had already set.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
kind-e2e-test (v1.22.17) failed with the bucket-create job exhausting
its retries; the new per-pod diagnostics from a prior commit did fire
this time and showed the mc container actually ran and crashed
repeatedly (Reason: Error, 4 restarts, kubelet BackOff) rather than
being stuck Pending - ruling out a minio-readiness race, which rolled
out in ~3s. The container's actual logs were still unavailable though:
the pod was already Terminating by the time we looked, most likely
because the Job controller kills the active pod right after
backoffLimit is exceeded, racing our own kubectl logs call. Retry with
--previous, which targets the last fully-exited container instance
instead of the one mid-teardown, so it isn't lost to that race.

Also pin minio/minio and minio/mc to explicit RELEASE tags instead of
:latest. MinIO stopped publishing to Docker Hub and archived
minio/minio in early 2026, so :latest is frozen rather than a moving
target today - but pinning removes the dependency on however Docker
Hub ends up serving :latest for an archived repo going forward, and
rules image drift out as a variable in this flake.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
…ipping it

drainScalingDownWorkers previously skipped re-issuing DecommissionWorkers
whenever a decommission attempt was merely tracked (RuntimeWorkerDecommissioning
condition present), regardless of whether that attempt actually reached the
Alluxio master. A transient failure (network glitch, master pod restarting)
would still record the condition on the first reconcile, so every subsequent
reconcile skipped retrying it entirely and just polled a worker count that
could never drop - the scale-down would sit doing nothing until the 10m
deadline forced an ungraceful proceed, even though a simple retry next
reconcile would likely have succeeded.

Add RuntimeWorkerDecommissionFailedReason and set it on the condition
whenever the attempt that produced it failed, so drainScalingDownWorkers can
tell "attempted and failed" apart from "attempted and reached the master" via
decommissionSucceeded(), and only skip re-issuing the command in the latter
case. decommissionStart continues to anchor the condition's
LastTransitionTime across these Reason transitions, so the deadline clock is
unaffected by how many times the Reason flips between failed and reached.

Signed-off-by: Monika Jakhar <jakharmonika364@gmail.com>
@jakharmonika364 jakharmonika364 force-pushed the feat-alluxio-scaledown-e2e branch from 0b2cb59 to 91896b6 Compare July 13, 2026 07:12
@sonarqubecloud

Copy link
Copy Markdown

@jakharmonika364

Copy link
Copy Markdown
Contributor Author

@cheyang — rebased onto latest master in 91896b6 to pick up your review feedback plus commit 676f47a. All 5 kind-e2e-test jobs are showing red, but the alluxioruntime graceful scale-down e2e test this PR actually touches passed cleanly in all 5:

  • v1.22.17: SUCCEEDED at 07:29:51
  • v1.24.17: SUCCEEDED at 07:29:55
  • v1.28.15: SUCCEEDED at 07:29:22
  • v1.30.13: SUCCEEDED at 07:29:28
  • v1.33.2: SUCCEEDED at 07:29:44

The actual failure in every job is a later, unrelated test case in the same suite: "curvine cache runtime basic e2e" times out with dataload curvine-dataload status is Executing, not complete for 60s!. This branch doesn't touch any curvine code. I rebased hoping 676f47a ("fix runtime config not mount error for cacheruntime dataload") would resolve it, but the failure is identical before and after, so it looks like either a different curvine issue or a flake (possibly the 60s timeout being too tight under the resource contention of 5 parallel matrix jobs).

Is this a known issue on your end, or should I open a separate issue for it? Happy to re-run the jobs if you think it's just a flake, but wanted to flag it rather than assume.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants