Skip to content

Add RayService serving and runtime revision detail - #1893

Merged
nadaverell merged 4 commits into
mainfrom
nadav/rayservice-detail
Sep 24, 2026
Merged

nadaverell merged 4 commits into
mainfrom
nadav/rayservice-detail

Conversation

@nadaverell

Copy link
Copy Markdown
Contributor

Why

A RayService can keep serving through its active RayCluster while a replacement head is crash-looping. A generic resource view and one aggregate lifecycle badge do not explain that state, and the embedded RayCluster status can omit the pending failure entirely.

This adds native RayService detail to the drawer and fullscreen view: proxy readiness stays separate from rollout/suspension, and each named active or pending revision carries its own application and runtime evidence.

Behavior and design

  • Show controller readiness, endpoint count, upgrade/rollback, suspension intent and acknowledgement independently. Lifecycle badges use conditions rather than deprecated serviceStatus as readiness proof.
  • Show native Serve application/deployment states and messages. Failures rank first; each list is bounded to 20 with explicit truncation. Missing snapshots remain unreported, including the active application map KubeRay clears during NewCluster upgrades.
  • Keep reported Serve target capacity and configured traffic share distinct from measured traffic; absent values are not zero.
  • The host performs at most two exact named RayCluster reads through the existing resource hook. Runtime conditions are attributed only after matching the child identity and controller owner group/kind/name/UID. Loading, missing, unreadable and mismatched children remain explicit. Embedded child status is not treated as live evidence.
  • Share the lifecycle freshness rule between table/detail badges and condition tones. KubeRay does not restamp unchanged conditions and can retain the root observed generation during failure or suspension. Positive readiness/rollout observations can be stale; reported failure and suspension states retain their native meaning alongside the generation difference.

The renderer is gated to ray.io/v1, reuses existing sections/badges/conditions/navigation, and takes optional host-provided runtime evidence. No new endpoint, schema, RBAC grant, resource-list fanout or topology adapter. Integration documentation describes these boundaries.

Validation

  • make tsc, make test, make build passed.
  • Full shared UI and web suites passed (3,950 and 1,521 tests respectively); focused final regressions passed (127 shared and 9 host tests).
  • Live AWS test with existing KubeRay 1.6.1: healthy serving/application baseline; then a failing pending head with the active endpoint still returning the expected response. Verified direct child failure messages updated automatically as backoff advanced, and revision navigation retained the exact API group.
  • Visual review covered drawer/fullscreen, 1280/1920 widths and light/dark themes. Synthetic browser/unit cases cover rollback, suspension, generation lag, denied children, long messages, large application lists, explicit zero percentages, foreign identities and ownership mismatch. KubeRay 1.7 suspension/rollback are not claimed as live-tested.

Scope and limits

Blast radius is RayService status presentation and exact-v1 detail, plus two bounded read-only child queries. Existing generic detail remains for other identities/versions. This is controller-reported state, not request-rate/latency observability, a live Serve dashboard, or a generated Service/Pod inventory. After a spec correction, a previously reported failure can remain visible until the next controller reconciliation; the generation difference remains explicit.

@nadaverell
nadaverell requested a review from hisco as a code owner September 24, 2026 22:36
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add native RayService serving and runtime revision detail

✨ Enhancement 🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Adds exact-v1 RayService detail for serving lifecycle, revisions, and native Serve health.
• Reads two named RayClusters and validates ownership before attributing runtime evidence.
• Preserves failure and suspension semantics across generation lag with tests and documentation.
Diagram

sequenceDiagram
  actor User
  participant View as Workload View
  participant Dispatch as Renderer Dispatch
  participant Wrapper as Web Wrapper
  participant API as Kubernetes API
  participant Base as Shared Renderer
  User->>View: Open RayService
  View->>Dispatch: Provide override
  Dispatch->>Wrapper: Render exact v1
  Wrapper->>API: Read named clusters
  API-->>Wrapper: Return child status
  Wrapper->>Wrapper: Validate ownership
  Wrapper->>Base: Supply runtime evidence
  Base-->>User: Show native detail
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use embedded RayCluster status
  • ➕ Avoids additional Kubernetes API reads
  • ➕ Keeps all rendering within the shared component
  • ➖ Embedded status can omit pending revision failures
  • ➖ Evidence may be stale and cannot prove current child state
2. Add a backend aggregation endpoint
  • ➕ Could consolidate RayService and child data into one response
  • ➕ Could later support broader generated-resource inventory
  • ➖ Requires new endpoint, schema, permissions, and maintenance
  • ➖ Expands the blast radius beyond status presentation
  • ➖ May introduce unnecessary resource-list fanout

Recommendation: Keep the PR's shared-renderer plus host-provided evidence design. Two bounded exact-name reads reuse existing infrastructure, while strict identity and controller-owner validation prevents foreign or recreated children from being attributed; this provides fresher evidence without adding APIs, RBAC, or broad list queries.

Files changed (11) +387 / -37

Enhancement (5) +164 / -3
RayServiceRenderer.tsxAdd shared native RayService detail renderer +114/-0

Add shared native RayService detail renderer

• Renders serving lifecycle, active and pending revisions, capacity and traffic fields, and native Serve application and deployment states. Bounds status lists to 20 entries with failures first and accepts optional host-provided runtime evidence.

packages/k8s-ui/src/components/resources/renderers/RayServiceRenderer.tsx

index.tsExport the RayService renderer +2/-0

Export the RayService renderer

• Exposes the new shared RayService renderer through the renderer barrel.

packages/k8s-ui/src/components/resources/renderers/index.ts

ResourceRendererDispatch.tsxDispatch exact-v1 RayServices to native detail +8/-3

Dispatch exact-v1 RayServices to native detail

• Registers RayService as a known group-gated kind, adds a host renderer override, and selects native rendering and status only for ray.io/v1. Other identities continue through generic detail.

packages/k8s-ui/src/components/shared/ResourceRendererDispatch.tsx

RayServiceRenderer.tsxInject directly observed RayCluster runtime evidence +38/-0

Inject directly observed RayCluster runtime evidence

• Wraps the shared renderer with up to two exact RayCluster reads for active and pending revisions. Attributes filtered runtime conditions only after validating API identity, namespace, name, and controller owner name and UID.

web/src/components/resources/renderers/RayServiceRenderer.tsx

WorkloadView.tsxRegister the web RayService renderer override +2/-0

Register the web RayService renderer override

• Adds the host-specific RayService wrapper to the stable renderer override map used by drawer and fullscreen workload views.

web/src/components/workload/WorkloadView.tsx

Bug fix (1) +26 / -32
resource-utils-ray.tsRefine RayService lifecycle and freshness evaluation +26/-32

Refine RayService lifecycle and freshness evaluation

• Adds shared generation freshness helpers and derives RayService badges from controller conditions. Preserves failure and suspension observations across generation lag while marking stale positive readiness and rollout states.

packages/k8s-ui/src/components/resources/resource-utils-ray.ts

Tests (4) +180 / -1
RayServiceRenderer.test.tsxTest native RayService detail behavior +62/-0

Test native RayService detail behavior

• Covers independent readiness and rollout signals, suspension semantics, absent values, application truncation, failure ordering, generation lag, and condition severity handling.

packages/k8s-ui/src/components/resources/renderers/RayServiceRenderer.test.tsx

resource-utils-ray.test.tsTest RayService lifecycle badge semantics +33/-1

Test RayService lifecycle badge semantics

• Verifies rollback precedence, suspension intent versus acknowledgement, stale positive observations, preserved failures, and removal of deprecated serviceStatus readiness fallback.

packages/k8s-ui/src/components/resources/resource-utils-ray.test.ts

ResourceRendererDispatch.test.tsxTest exact RayService API version dispatch +16/-0

Test exact RayService API version dispatch

• Ensures ray.io/v1 receives native detail while foreign, future, and alpha API versions retain generic rendering and no specialized status.

packages/k8s-ui/src/components/shared/ResourceRendererDispatch.test.tsx

RayServiceRenderer.test.tsxTest bounded RayCluster runtime observation +69/-0

Test bounded RayCluster runtime observation

• Verifies exact named reads, loading and error states, freshness, missing conditions, promotion, recreation, and strict child identity and controller ownership checks.

web/src/components/resources/renderers/RayServiceRenderer.test.tsx

Documentation (1) +17 / -1
integrations.mdDocument native RayService status and runtime evidence boundaries +17/-1

Document native RayService status and runtime evidence boundaries

• Documents serving, rollout, suspension, revision, and freshness semantics. Clarifies bounded child reads, ownership validation, missing snapshots, and unsupported topology or inventory behavior.

docs/integrations.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Runtime failures bypass standard alerts ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
RuntimeEvidence renders read and ownership failures as custom warning-colored paragraphs instead
of AlertBanner, ProblemAlerts, or ConditionsSection. A missing, unreadable, foreign,
recreated, or incorrectly owned RayCluster reaches this bespoke problem presentation while condition
failures use the shared section.
Code

web/src/components/resources/renderers/RayServiceRenderer.tsx[17]

+  if (query.error) return <p className="mt-2 text-sm text-warning-text">{query.error instanceof ApiError && query.error.status === 404 ? 'The named RayCluster was not found; it may have been cleaned up.' : `Could not read RayCluster: ${query.error.message}`}</p>
Evidence
Rule 3036704 requires user-facing renderer problems to use a standard alert or conditions component.
The new renderer directly presents read failures and ownership mismatches with custom `` elements at
lines 17 and 21.

Rule 3036704: Use standard problem and label selector components in renderers
web/src/components/resources/renderers/RayServiceRenderer.tsx[17-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`RuntimeEvidence` uses custom warning paragraphs for RayCluster read and ownership problems instead of the standard renderer alert components.
## Fix Focus Areas
- web/src/components/resources/renderers/RayServiceRenderer.tsx[17-21]
## Recommended Fix
Replace the read-error and ownership-mismatch paragraphs with `AlertBanner` instances using appropriate semantic variants, titles, and messages while preserving the existing error distinctions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Runtime failures appear inconclusive 🐞 Bug ≡ Correctness
Description
RuntimeEvidence overrides runtimeConditionTone with unknown for every condition whenever the
RayCluster root observation is stale. When generation lag accompanies
RayClusterReplicaFailure=True or HeadPodReady=False, their explicit failure and warning tones
are lost even though the condition text remains displayed.
Code

web/src/components/resources/renderers/RayServiceRenderer.tsx[27]

+    {conditions.length === 0 ? <p className="mt-2 text-sm text-theme-text-secondary">Runtime conditions are not reported by this RayCluster.</p> : <ConditionsSection conditions={conditions} getConditionTone={condition => stale ? 'unknown' : runtimeConditionTone(condition)} defaultExpanded />}
Evidence
The local tone function explicitly classifies replica failure as fail and negative head readiness
as warning, but the callback on line 27 bypasses those classifications whenever the root
generation lags. The shared freshness helper documents that KubeRay can freeze observed generation
during failures and suspension and therefore only marks positive readiness and rollout observations
stale, while the added host test covers only stale positive readiness.

web/src/components/resources/renderers/RayServiceRenderer.tsx[8-12]
web/src/components/resources/renderers/RayServiceRenderer.tsx[22-27]
packages/k8s-ui/src/components/resources/resource-utils-ray.ts[144-148]
web/src/components/resources/renderers/RayServiceRenderer.test.tsx[30-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Generation lag currently changes every RayCluster condition tone to unknown, including directly reported failures. Preserve failure and suspension meanings while treating only positive readiness or provisioning observations as stale.
## Fix Focus Areas
- web/src/components/resources/renderers/RayServiceRenderer.tsx[8-12]
- web/src/components/resources/renderers/RayServiceRenderer.tsx[22-27]
## Recommended Fix
Apply the stale neutral tone selectively to positive readiness-like conditions such as `HeadPodReady=True` and `RayClusterProvisioned=True`. Continue passing failure, negative readiness, and suspension conditions through `runtimeConditionTone`, and add tests covering a stale replica failure and stale `HeadPodReady=False`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can choose which labels appear on a finding, and whether they show icons or text

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread web/src/components/resources/renderers/RayServiceRenderer.tsx Outdated
Comment thread web/src/components/resources/renderers/RayServiceRenderer.tsx
@nadaverell

Copy link
Copy Markdown
Contributor Author

bugbot run

@cursor

cursor Bot commented Sep 24, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@nadaverell
nadaverell merged commit 4d278db into main Sep 24, 2026
8 checks passed
@nadaverell
nadaverell deleted the nadav/rayservice-detail branch September 24, 2026 22:54
nadaverell added a commit that referenced this pull request Sep 27, 2026
Adds the v1.15.0 entry to the What's New catalog. This replaces #1877,
which was stacked on the closed #1876; the dialog landed on main in
#1902 instead. `scripts/check-whats-new.sh` (#1908) refuses to release
v1.15.0 without this entry, so this must merge before the tag.

## Highlights
A full-width lead card, then a 2x2 grid. Each secondary card has its own
icon color, so they read apart.

1. **AI investigations that show their work** (lead, no CTA; the
investigations workspace redirects home in run modes that can't host
local agents). This recaps the v1.14.1 rework (#1766, #1802) on purpose:
it's the first What's New dialog, and we want to put AI investigations
in front of people. OpenCode (#1265) is the new v1.15 part.
2. **Full manifest diffs for Argo CD resources** (#1622)
3. **Rightsizing and cost data in MCP**: new agent tools, and risks lead
before savings in the UI too (#1820, #1723)
4. **Deeper batch + AI/ML workloads support**: Kueue, JobSet and Ray
pages; Job and JobSet details show why a queued job has no Pods (#1874,
#1885, #1900, #1849, #1893, #1897)
5. **Canary and blue-green in Topology** (#1626)

## Also in this release
Eight one-liners, paired by length because the grid fills row by row:
table sort memory (#1428), OCI Helm installs (#1815), expiring TLS
certificates in Checks (#1829), Radar Desktop keeping preferences across
restarts (#1907), Pod vs template in Issues (#1848), PVC usage
availability (#1828), Strimzi and admission webhook failures in Issues
(#1840, #1830), `--listen-address` (#1845).

Left out: security fixes, dependency bumps, refactors and CI,
accessibility work (#1901, #1909), and narrow items (ALB action
annotations, INSTALL_DIR). No usage-stats line is needed, because
#1879's consent question already sits in this dialog.

## UI changes beyond the catalog
- The heading names the release line (`v1.15`, via `releaseLine`), since
patch releases show the same notes. The "You just updated from → to"
line keeps exact versions.
- An optional `tone` on highlights colors the icon tile (violet, teal,
emerald, indigo). It uses Radar's existing `bg-X-500/10 text-X-600
dark:text-X-400` pattern, and was checked in light and dark themes.

## Verification
- `scripts/check-whats-new.sh v1.15.0` → found notes
- `make tsc` clean; What's New and usage-data tests: 39 passed
- Previewed live with `VERSION=v1.15.0 make build`, opening
`/?whats-new`, with #1879's consent question in place

The matching public changelog is skyhook-dev/marketing#312.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Release-notes catalog and presentational What's New UI only; no auth,
API, or data-handling changes.
> 
> **Overview**
> Adds the **v1.15.0** What's New catalog entry (five highlights with
CTAs where appropriate, plus eight improvement one-liners) so
`check-whats-new` can ship the tag.
> 
> The dialog heading now shows the **minor release line** via new
`releaseLine()` (e.g. `v1.15` instead of `v1.15.0`), while the upgrade
subtitle still uses exact versions. Secondary highlight cards can set an
optional **`tone`** (violet, teal, emerald, indigo) for distinct icon
tiles; the lead card stays on the accent style.
> 
> Tests cover `releaseLine` and the preview dialog title expectation.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f0038c3. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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.

1 participant