Skip to content

fix(anolisa): fallback to v1 components.toml when v2 index is unavailable - #2566

Open
zhangtaibo wants to merge 4 commits into
alibaba:mainfrom
zhangtaibo:fix/component-index-v2-fallback
Open

fix(anolisa): fallback to v1 components.toml when v2 index is unavailable#2566
zhangtaibo wants to merge 4 commits into
alibaba:mainfrom
zhangtaibo:fix/component-index-v2-fallback

Conversation

@zhangtaibo

Copy link
Copy Markdown
Collaborator

Problem

Fixes #2565

anolisa list hard-fails with HTTP 404 when the CDN mirror has not yet published components-v2.toml. Commit 52fa3159 switched from reading v1 components.toml to v2 components-v2.toml, but the v2 file is not yet deployed. The v1 URL helper was gated behind #[cfg(test)], making it inaccessible in release builds. This is a regression introduced today (2026-08-14 13:58).

Fix

- #[cfg(test)]
  pub fn component_index_url(base_url: &str) -> String {

Three coordinated changes in resolution.rs and repo_config.rs:

  1. Remove #[cfg(test)] from component_index_url() in repo_config.rs:698 so the v1 URL is available in release builds.

  2. Add v2→v1 fallback in load_component_index(): if v2 fetch returns Fetch { reason: "http status 404 ..." }, retry with the v1 URL. Extract fetch logic into a fetch_index_url() helper to keep the main function readable.

  3. Make the parser accept both schemas:

    • Add #[serde(default)] to targets: Vec<ComponentTarget> so v1 entries (which lack targets) deserialize as an empty vec.
    • Accept schema_version 1 and 2 in validate() (use matches!(self.schema_version, 1 | 2) instead of != 2).
    • Skip the "must declare at least one target" check for schema v1 entries (guarded by self.schema_version >= 2).
    • Update the unsupported_schema_is_rejected unit test to only test schema 99 (no longer 1).

The v1 index on the mirror (components.toml) uses schema_version = 1 and lacks the targets field introduced in v2. With #[serde(default)] the v1 rows parse successfully with targets = [], and the validator treats them as "no target info" — acceptable for the transition window.

Verification

On ALinux 4 ECS (8.217.123.80):

$ cd anolisa/src/anolisa
$ cargo build -p anolisa-cli --release
   Compiling anolisa-cli v0.3.1
    Finished `release` profile [optimized + debuginfo] target(s) in 2m 46s

$ cargo test -p anolisa-cli --release
test result: ok. 814 passed; 0 failed; 1 ignored

$ ./target/release/anolisa -q list
# stdout empty, exit 0 (quiet mode correct)

$ ./target/release/anolisa list
Components for Linux/x86_64
NAME            AVAILABILITY    SCOPE     LOCAL STATE      ACTION
cosh             only           system    observed         -
cosh-ng          only           none      not_installed    -
...
# exit 0, 9 components displayed

$ ./target/release/anolisa status
NAME                          SCOPE     STATUS          VERSION
sec-core                      system    adopted         0.10.1-1.alnx4
# exit 0, unaffected

$ ./target/release/anolisa --no-color list
# exit 0, no ANSI codes in output

Verified 2/2 stable runs.

Co-Authored-By: Hermes Agent noreply@nousresearch.com

…able

When the CDN mirror has not yet published components-v2.toml (HTTP 404),
load_component_index() now gracefully falls back to the v1 components.toml
file. This prevents 'anolisa list' from hard-failing in the transition
window between schema v1 and v2 deployment.

Changes:
- Remove #[cfg(test)] from component_index_url() in repo_config.rs so
  the v1 URL is available in release builds.
- Add v2→v1 fallback in load_component_index(): if v2 fetch returns
  HTTP 404, retry with the v1 URL.
- Make ComponentIndex::validate() accept schema v1 and v2 (use
  matches!(1 | 2) instead of != 2).
- Add #[serde(default)] to the targets field so v1 entries (which lack
  targets) deserialize as an empty vec.
- Skip the non-empty targets check for schema v1 entries.
- Extract fetch logic into fetch_index_url() helper.
- Update unsupported_schema_is_rejected test to only test schema 99.

Fixes alibaba#2565

Verified: cargo build -p anolisa-cli --release → exit 0
          cargo test -p anolisa-cli --release → 814 passed, 0 failed
          anolisa -q list → exit 0 (quiet mode correct)
          anolisa list → exit 0, displays 9 components
          anolisa status → exit 0 (unaffected)

Co-Authored-By: Hermes Agent <noreply@nousresearch.com>

@qoderai qoderai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

  • v2→v1 回退逻辑依赖 404 文案字符串匹配,建议改为结构化状态码判断。
  • schema v1/v2 接受策略依赖隐式 targets 默认值,后续 schema 升级需同步更新匹配逻辑与测试。

🤖 Generated by QoderView workflow run


let cache = DownloadCache::new(layout.cache_dir.clone());
let downloaded = match fetch_index_url(&cache, &url) {
Ok(art) => art,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P1] v1 回退逻辑依赖错误文案匹配,易受服务端文案变动影响

当前 v2→v1 回退通过 reason.contains("http status 404") 识别 404,resolution.rs:752-755。一旦底层 download 层调整错误信息格式(如本地化、移除 http status 前缀),v1 回退会静默失效,重新暴露 404 硬失败。建议显式携带/匹配 HTTP 状态码(或定义结构化错误枚举),在 404 时触发回退,避免对 free-text 文案的脆弱依赖。


🤖 Generated by QoderFix in Qoder

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5c50ed5e7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let downloaded = match fetch_index_url(&cache, &url) {
Ok(art) => art,
Err(ComponentIndexError::Fetch { ref reason })
if reason.contains("http status 404") =>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat file:// missing v2 as absent

For local file:// repositories, a missing components-v2.toml is reported by DownloadCache::fetch as an I/O NotFound, not as an http status 404, so this guard never falls back to components.toml. That leaves v1-only local or mirrored repos failing to load even though the new code is meant to handle an unavailable v2 index; use typed absence detection like the raw index path does for HTTP 404/410 and file NotFound before wrapping the error.

Useful? React with 👍 / 👎.

#[serde(default)]
pub(crate) summary: Option<String>,
/// Supported host OS/architecture combinations.
#[serde(default)]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Populate targets when accepting v1 indexes

When the fallback loads a schema v1 components.toml, existing v1 rows use platforms = [...] rather than targets, so defaulting targets to an empty list makes supports_target() false for every component. In particular, install --all filters through component_names_for_target() and will report nothing to install even though the fallback index was loaded; translate v1 platform data into target availability or avoid target filtering for schema v1.

Useful? React with 👍 / 👎.

@kongche-jbw kongche-jbw 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.

Review baseline: a50e34de6130727d97ea89c4ff76a76d59bc9b9d...e5c50ed5e738feee9d0de769861a5e96774bb3f6

[P1] 恢复必需的 Rust 格式与 clippy 门禁

src/anolisa/crates/anolisa-cli/src/resolution.rs:16 未通过
cargo fmt --all -- --check。格式修复后,同文件 :1363 的单元素循环仍会触发
clippy::single-element-loop。当前 Test anolisa 已因此失败,后续测试步骤不会运行,
PR 无法通过必需 CI。

Possible direction: 运行 rustfmt,并将 schema 99 检查改为直接断言;随后执行
cargo clippy --all-targets --locked -- -D warnings 和完整测试。

zhangtaibo and others added 3 commits August 14, 2026 22:51
…andling

Apply cargo fmt to the multiline format!() call in the v1 fallback error
message, collapsing it to a single line as rustfmt requires.

This fixes the CI 'Check formatting' step failure in PR alibaba#2566.

Signed-off-by: Hermes Agent <hermes@alibaba-inc.com>
- Split long import line for component_index_url/v2_url into multi-line
- Collapse match arm guard pattern to single line

Co-authored-by: Hermes Agent <hermes@alibaba-inc.com>
Replace for-loop over single element [99] with direct let binding
as clippy recommends. The loop was originally written for multiple
schema versions but was reduced to one when v1/v2 acceptance was added.

Co-authored-by: Hermes Agent <hermes@alibaba-inc.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Nightly][anolisa] bug: anolisa list hard-fails when mirror lacks components-v2.toml (HTTP 404, no v1 fallback)

2 participants