Skip to content

feat(FR-2592): validate deployment-config.yaml in the vfolder file editor - #9514

Draft
yomybaby wants to merge 2 commits into
mainfrom
feat/FR-2592-deployment-config-yaml-editor-support
Draft

feat(FR-2592): validate deployment-config.yaml in the vfolder file editor#9514
yomybaby wants to merge 2 commits into
mainfrom
feat/FR-2592-deployment-config-yaml-editor-support

Conversation

@yomybaby

@yomybaby yomybaby commented Sep 7, 2026

Copy link
Copy Markdown
Member

Resolves #6750 (FR-2592)

What changed

The model-folder deployment config moved from service-definition.toml to deployment-config.yaml. The manager reads the yaml first and keeps the toml only as a deprecated fallback (repositories/deployment/repository.py:122-123, :572-573), and the shipped manual documents exactly that relationship (packages/backend.ai-webui-docs/src/en/deployment/deployment.md:414-470). The Monaco schema map in the vfolder file editor still knew only the legacy filename, so the current format got no validation and no completion at all.

  • New resources/deployment-config.schema.json. Authored from the manager's DeploymentConfigInput (src/ai/backend/manager/repositories/deployment/storage_source/storage_source.py:26-40image, architecture, resource_slots, resource_opts, environ, extra="ignore") and the manual's field reference. Covers the root-level defaults, the documented environment: grouping, and runtime-variant sections (any other top-level key, per the manual's three-level override hierarchy).
  • deployment-config.yaml → that schema in definitionSchemaMap. The yaml validator + completion wiring already exists (it serves model-definition.yaml), so no new plumbing.
  • The legacy service-definition.toml entry now points at the same schema and is marked deprecated. It stays mapped, since the manager still reads it.

Design decisions

  • No deployment-config.yml twin. The manager's candidate list names only deployment-config.yaml (repository.py:122), unlike model-definition, whose path the caller supplies. Mapping .yml would give editor help for a filename the manager never reads.
  • Repointing the legacy toml entry is a bug fix, not scope creep. resources/service-definition.schema.json describes a different artifact — the container service-def JSON files under /etc/backend.ai/service-defs/ ($id/description at :3-5; required: ["command"]). A model-folder service-definition.toml has none of those keys, so main today warns on every valid file. The manager parses both filenames into the same DeploymentConfigInput, so sharing the schema is what matches reality. service-definition.schema.json is left in place — it still describes the container files.
  • The schema declares both environment: {image, architecture} and root-level image / architecture. The manual documents the nested grouping; the manager reads the flat pair. Declaring only one would make the other warn.
  • Nothing is required and validation is warning-level (monacoSchemaValidator.ts emits MarkerSeverity.Warning), so no existing file starts failing.

Out of scope, left alone: the two stale doc comments in VFolderNodes*.tsx and the e2e fixtures that still use the legacy filename — the legacy name is still supported, so those assertions remain valid. No i18n key references either filename any more.

Tests

  • New react/src/helper/deploymentConfigSchema.test.ts — compiles the schema with the same Ajv2020({ allErrors: true }) the editor uses and asserts: the manual's full documented example validates, the manager's flat root pair validates, an empty file validates, and a non-string environ value / a scalar runtime-variant section / a non-scalar resource slot each produce a finding at the right instance path. pnpm exec vitest run src/helper/deploymentConfigSchema.test.ts → 6 passed.
  • bash scripts/verify.sh (full harness).
  • No CSS/token changes, so the Astryx token gate was not applicable.

Verification

=== ALL PASS ===

Review notes

  • Open a model-type folder's file explorer, create deployment-config.yaml, and edit it: typing at the root should complete environment / resource_slots / resource_opts / environ, and environ: { PORT: 8080 } should raise a warning squiggle (values must be strings).
  • Open a legacy service-definition.toml in a model folder: the spurious root: must have required property 'command' warning from the container service-def schema is gone.
  • The schema is served from the repo-root resources/ tree (copyresource in package.json:34), same as the two existing *.schema.json files — nothing else to wire up.

Checklist: (if applicable)

  • Documentation — no change needed; the manual already documents deployment-config.yaml as current and the toml as a deprecated fallback.
  • Minium required manager version
  • Specific setting for review (eg., KB link, endpoint or how to setup) — needs a model-type vfolder to open the file editor against.
  • Minimum requirements to check during review
  • Test case(s) to demonstrate the difference of before/after — see the vitest file above.

https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ

…itor

The model-folder deployment config moved from `service-definition.toml`
to `deployment-config.yaml`: the manager reads the yaml first and keeps
the toml only as a deprecated fallback (manager
repositories/deployment/repository.py:122-123, :572-573), and the shipped
manual documents it that way. The Monaco schema map in the vfolder file
editor still knew only the legacy filename, so the current format got no
validation or completion at all.

- Add `resources/deployment-config.schema.json`, authored from the
  manager's `DeploymentConfigInput`
  (repositories/deployment/storage_source/storage_source.py:26-40) and
  the manual's field reference
  (packages/backend.ai-webui-docs/src/en/deployment/deployment.md:414-470):
  the root-level `environment` / `image` / `architecture` /
  `resource_slots` / `resource_opts` / `environ` defaults, plus
  runtime-variant sections as additional top-level keys.
- Map `deployment-config.yaml` to it. No `.yml` twin — the manager's
  candidate list names only `deployment-config.yaml`.
- Repoint the legacy `service-definition.toml` entry at the same schema.
  The manager parses both filenames into the same payload, while
  `service-definition.schema.json` describes the unrelated container
  service-def files under /etc/backend.ai/service-defs/ and required a
  `command` key a model-folder file never has, so every valid file was
  warned about. The entry stays, marked deprecated.

Every field is optional and validation is warning-level, so no existing
file starts failing.

Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ
@github-actions github-actions Bot added size:L 100~500 LoC type:enhance Add new features labels Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 15.63% 5691 / 36394
🔵 Statements 13.11% 6933 / 52866
🔵 Functions 13.68% 887 / 6482
🔵 Branches 9.48% 4795 / 50563
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
react/src/components/VFolderTextFileEditorModal.tsx 3.63% 0% 0% 3.84% 35-38, 74-83, 122-421
Generated in workflow #742 for commit 89ebeef by the Vitest Coverage Report Action

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.

🟡 Changes recommended

The schema currently validates unsupported configuration forms and mishandles empty YAML documents.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds Monaco validation and completion for deployment configuration files.

Changes:

  • Adds a deployment configuration JSON schema.
  • Maps current YAML and legacy TOML filenames to the schema.
  • Adds schema validation tests.

Unresolved issues:

  • Runtime-variant sections and nested environment values are accepted but ignored by the manager.
  • Empty YAML parses as null, which the schema rejects.
  • The empty-file test validates {} instead of exercising validateYaml('').
File summaries
File Description
resources/deployment-config.schema.json Defines deployment configuration validation; requires alignment with manager behavior and empty YAML handling.
react/src/helper/deploymentConfigSchema.test.ts Tests schema behavior but does not cover the actual empty-file parsing path.
react/src/components/VFolderTextFileEditorModal.tsx Registers schema mappings for both filenames.
Review details

Suppressed comments (1)

react/src/helper/deploymentConfigSchema.test.ts:64

  • This bypasses the YAML parsing path and validates {}, so it does not cover an actually empty file: parse('') yields null, which the current schema rejects. Exercise validateYaml('') here so the production behavior is protected.
  it('accepts an empty file — every field is optional', () => {
    expect(validate({})).toBe(true);
  • Files reviewed: 3/3 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread resources/deployment-config.schema.json Outdated
Comment on lines +8 to +10
"environment": {
"$ref": "#/$defs/Environment"
},
Comment on lines +36 to +37
"additionalProperties": {
"$ref": "#/$defs/RuntimeVariantSection"
The editor validates `validate(parse(text))`, and `yaml.parse('')` returns
null, so a root `"type": "object"` made every brand-new (or comment-only)
deployment-config.yaml warn `root: must be object` — exactly the file the
PR's review notes ask a reviewer to create. The root type now also accepts
null.

The empty-file test asserted `validate({})`, which bypasses the parse path
and so could not catch this; it now goes through `validateYaml('')` and a
comment-only document, with the empty-mapping case kept separately.

Claude-Session: https://claude.ai/code/session_011RFmSEBxxxvCXyquSPtqVJ

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.

🔵 Needs a closer look

The schema exposes unsupported Manager fields, and dynamic runtime sections lack completion support.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

resources/deployment-config.schema.json:37

  • Runtime-variant fields validate here, but they receive no completion. getSchemaAtPath() in monacoYamlCompletion.ts only follows named properties; for a path such as vllm, it returns undefined instead of following this schema-valued additionalProperties, so typing inside vllm: yields no suggestions. Add an additionalProperties fallback to the completion traversal and cover a dynamic section in its tests.

resources/deployment-config.schema.json:9

  • The current Manager contract does not consume this nested object (or the arbitrary runtime-variant sections below): DeploymentConfigInput declares only flat image, architecture, resource_slots, resource_opts, and environ fields with extra="ignore", and the repository reads those flat attributes directly. Consequently, the editor now validates and suggests configurations whose image/variant defaults are silently discarded at deployment time. Either add Manager-side normalization/support first, or restrict this schema (and the manual) to the fields the Manager actually consumes.
    "environment": {
      "$ref": "#/$defs/Environment"
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

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

Labels

size:L 100~500 LoC type:enhance Add new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace service-definition.toml with deployment-config.yaml

2 participants