Skip to content

Feat per role resource custom - #138

Merged
aceforeverd merged 5 commits into
mainfrom
feat-per-role-resource-custom
Nov 13, 2026
Merged

aceforeverd merged 5 commits into
mainfrom
feat-per-role-resource-custom

Conversation

@aceforeverd

Copy link
Copy Markdown
Member

  1. Shared resource discovery, form-layer round-trip, and validation — resources.ts
      • helmResources parses merged defaults + overrides from the dry-run compose (helmValues) to extract top-level resources.requests, resources.limits, and model.gpuResource / model.gpus (plus pd.prefill / pd.decode GPU counts when pd.enabled is true).
      • gpuRequestSummary combines the selected form.gpuResource / vendor default with helmValues / cluster perPod GPUs so the requested GPU resource appears cleanly as the top read-only row.
      • resourceEditsFromLayer, applyResourceEdits, and dropClearedResources round-trip edits through form.resources -> overrides.resources, dropping cleared scalar overrides on upgrade while preserving explicit null deletions.
      • useResourceRows drives ordered Resource | Request | Limit rows: effective defaults appear as Tab-acceptable placeholders (Suggest), custom rows suggest common keys (cpu, memory, ephemeral-storage, hugepages-2Mi, hugepages-1Gi, rdma/hca_shared), entering the
      active GPU resource key (gpuReserved) or duplicate/existing keys is flagged inline, and hugepages-* without cpu/memory displays the Kubernetes / _pod.tpl compute hint.
  2. Reused the existing open/refresh dry-run query — useImageSlots.ts
      • previewForm strips resources overrides alongside images and edits so dry-run previews always reflect underlying chart/catalog/site defaults without extra /api/v2/compose calls.
      • useImageSlots returns resources?: HelmResources alongside slots.
  3. UI integration in both modules + i18n
      • DeploySettings.tsx, Deploy.tsx, Upgrade.tsx: wired Form.resources, planRequest, formFromPlan, and the Resources row in Advanced right after GPU capacity.
      • DeployForm.tsx, DeploySheet.tsx, en-US.json, zh-CN.json: added ResourceRows inside Resources and scheduling right after CapacityHint alongside GPU resource selection.
@aceforeverd
aceforeverd requested a review from huskcass November 13, 2026 11:03

@huskcass huskcass 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.

No blockers. CI is green apart from publish, which is still pending. Checked at f211264.

Medium

  • Overdesign in swiss/lib/resources.ts. useResourceRows mirrors draft rows into local state and keeps them in sync with value using lastEmittedRef, prevBaseKeysRef and an effect that reseeds or filters the drafts. That is a lot of machinery for a small table. Hold the custom rows in the form as an ordered array and derive the edits from it when planning. That removes the refs and the effect, and replaceCustomResources, customResourceRows and clearResourceOverride mostly go with them.
  • Speculative extras that can be cut: the COMMON_RESOURCE_KEYS dropdown plus SWISS_RESOURCE_LABELS and keyChoicesFor, and needsHugepageComputeHint, which is chart-internal knowledge copied into the UI. The issue asks for image, affinity and environment settings, not a hugepages assistant.
  • Duplicated logic in pdRoles.ts. extractStandaloneGpuTerm and extractAnyGpuProducts walk the same affinity tree with different filters. applyPdOverrides carries a long branch that rebuilds or nulls affinityReplace for the clear case. Writing the one role term and clearing it by removing that term would be much smaller. Several helpers (parseNonNegNumber, parsePosInt, hasAnyAffinityRule, expandProductValues, canonicalizeProducts) guard shapes that the dry-run output never produces.
  • The compose dry run used to be gated on opening Images. It now always runs once the form is seeded, and again on target changes. That is an extra compose call on every Deploy/Upgrade open. It matches the commit "dryRun moved to window first open", so confirm that is intended. The new header "Refresh" button on both routes is a second control that does the same thing as the old Images refresh.

Low

  • onRefresh ?? (() => {}) in PdRolesRows hides a missing prop. Make it optional on CapacityLine, or make it required.
  • resources.test.ts, pdRoles.test.ts and DeploySettings.pd.test.tsx add about 700 lines, mostly testing the helpers listed above. They will shrink once the helpers do.
  • Custom rows whose key matches the GPU resource or a base key are dropped from the emitted edits without a trace. That is only visible as the inline warning while the row is on screen.

Solid

  • Old behaviour is kept: images still go through the form layer, dropClearedResources only removes scalars the form owns, and colocate mode keeps the top-level scheduling.
  • The Images section moving into Advanced matches the issue.

Verdict: OK to merge as is. The Medium items are simplifications I would make before this grows further.

— Review Golden

Hold custom resource rows on the form as an ordered array and derive
edits at plan time, dropping the draft-state sync. The custom-row key
is a plain text input. PD affinity overrides now write or remove one
role term. Capacity refresh is optional, and conflicting custom keys
are kept in the edits with the existing inline warning.

Co-authored-by: aceforeverd <11715200+aceforeverd@users.noreply.github.com>

@huskcass huskcass 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.

No blockers.

The previous Medium cuts landed: custom rows now live in the form as an ordered array (no draft state, refs or effect), the key dropdown, labels and hugepage hint are gone, pdRoles.ts reads affinity in one walk and the clear path just removes the role's term. expandProductValues/canonicalizeProducts are on the write path (applyPdOverrides), so keeping them is right. Conflicting custom rows are now kept with a warning.

  • Low: clearRoleGpuTerm re-checks nodeAffinity / required being maps after nodeSelectorTermsOf already found terms; those two guards can go. formRoleGpu is a thin wrapper that can be inlined.
  • Low: custom rows use key={i}; removing a middle row reuses the next row's inputs. Fine for controlled inputs, just noting it.
  • Low: dry run on first open plus the header Refresh is unchanged; fine as the intended behaviour.

Verdict: good to merge.

— Review Golden

@aceforeverd
aceforeverd enabled auto-merge (squash) November 13, 2026 14:33
@aceforeverd
aceforeverd disabled auto-merge November 13, 2026 14:33
@aceforeverd
aceforeverd merged commit 2ae2cab into main Nov 13, 2026
4 checks passed
@aceforeverd
aceforeverd deleted the feat-per-role-resource-custom branch November 13, 2026 14:34
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.

2 participants