-
Notifications
You must be signed in to change notification settings - Fork 94
LCORE-2337: Migration tool — dumb-mode lift-and-shift #2029
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,8 @@ | |
| operator-facing artifact. | ||
| """ | ||
|
|
||
| # pylint: disable=too-many-lines | ||
|
|
||
| import copy | ||
| import os | ||
| from argparse import ArgumentParser | ||
|
|
@@ -900,6 +902,70 @@ def synthesize_to_file( | |
| logger.info("Wrote synthesized Llama Stack configuration to %s (mode 0600)", path) | ||
|
|
||
|
|
||
| # ============================================================================= | ||
| # Migration: legacy two-file config -> unified single file (LCORE-2337) | ||
| # ============================================================================= | ||
|
|
||
|
|
||
| def migrate_config_dumb( | ||
| run_yaml_path: str, | ||
| lightspeed_yaml_path: str, | ||
| output_path: str, | ||
| ) -> None: | ||
| """Migrate a legacy two-file config to a unified single file (dumb mode). | ||
|
|
||
| "Dumb" lift-and-shift: the operator's ``lightspeed-stack.yaml`` is kept | ||
| verbatim except for its ``llama_stack`` section, where | ||
| ``library_client_config_path`` is dropped and replaced by a unified | ||
| ``config`` block that lifts the *entire* legacy ``run.yaml`` body into | ||
| ``native_override`` with ``baseline: empty``. Synthesizing the result then | ||
| starts from an empty baseline and deep-merges only the lifted run.yaml, so | ||
| it reproduces the original run.yaml (Decision T7) — a lossless round-trip, | ||
| without trying to factor anything into high-level sections (that "smart" | ||
| mode is deferred future work). | ||
|
|
||
| All other ``lightspeed-stack.yaml`` content (name, service, byok_rag, …) is | ||
| preserved untouched, so any existing enrichment keeps working in unified | ||
| mode exactly as it did in legacy mode. | ||
|
|
||
| Parameters: | ||
| run_yaml_path: Path to the legacy Llama Stack ``run.yaml``. | ||
| lightspeed_yaml_path: Path to the legacy ``lightspeed-stack.yaml``. | ||
| output_path: Path to write the unified ``lightspeed-stack.yaml``. | ||
|
|
||
| Returns: | ||
| None. | ||
|
|
||
| Raises: | ||
| OSError: If an input file cannot be read or the output cannot be | ||
| written. | ||
| yaml.YAMLError: If an input file is not valid YAML. | ||
| """ | ||
| with open(run_yaml_path, "r", encoding="utf-8") as file: | ||
| run_yaml = yaml.safe_load(file) | ||
| with open(lightspeed_yaml_path, "r", encoding="utf-8") as file: | ||
| lcs_config = yaml.safe_load(file) | ||
|
|
||
| # Preserve the whole lightspeed-stack.yaml; only rewrite the llama_stack | ||
| # section: drop the legacy path, add the unified config block. | ||
| llama_stack = dict(lcs_config.get("llama_stack") or {}) | ||
| llama_stack.pop("library_client_config_path", None) | ||
| llama_stack["config"] = { | ||
| "baseline": "empty", | ||
| "native_override": run_yaml, | ||
| } | ||
| lcs_config["llama_stack"] = llama_stack | ||
|
|
||
| logger.info( | ||
| "Migrating legacy config (%s + %s) to unified %s", | ||
| lightspeed_yaml_path, | ||
| run_yaml_path, | ||
| output_path, | ||
| ) | ||
| with open(output_path, "w", encoding="utf-8") as file: | ||
| yaml.dump(lcs_config, file, Dumper=YamlDumper, default_flow_style=False) | ||
|
Comment on lines
+965
to
+966
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win Consider restricting permissions on the migrated output file. The lifted 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| # ============================================================================= | ||
| # Main Generation Function (service/container mode only) | ||
| # ============================================================================= | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Empty
lightspeed-stack.yamlwill raise an opaqueAttributeError/TypeError.yaml.safe_loadreturnsNonefor an empty or comment-only file. Line 951 (lcs_config.get(...)) then raisesAttributeError, and line 957 (lcs_config["llama_stack"] = ...) would raiseTypeError— neither is among the documentedOSError/YAMLError. Guard for theNonecase to fail clearly.🛡️ Proposed guard
with open(lightspeed_yaml_path, "r", encoding="utf-8") as file: lcs_config = yaml.safe_load(file) + if not isinstance(lcs_config, dict): + raise ValueError( + f"{lightspeed_yaml_path} did not parse to a mapping; cannot migrate." + )📝 Committable suggestion
🤖 Prompt for AI Agents