-
Notifications
You must be signed in to change notification settings - Fork 160
chore(web): stop tracking static export #463
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
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 |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # upgrade 命令开发设计 | ||
|
|
||
| ## 命令实现目标 | ||
|
|
||
| `libra upgrade` 是不依赖仓库的 Libra 扩展:检查 Ed25519 签名的 stable | ||
| release manifest,并在用户确认或传入 `--yes` 后,以可回滚的安装事务替换官方 | ||
| 安装的当前二进制。它不读取或修改仓库状态;Git 没有对应命令。 | ||
|
|
||
| ## 对比 Git 与兼容性 | ||
|
|
||
| - 兼容级别:`intentionally-different`。 | ||
| - 已支持:默认交互检查和安装、`--check`(只报告)、`-y`/`--yes`(非交互安装), | ||
| 以及全局 `--json`/`--machine` 输出。 | ||
| - `--check` 与 `--yes` 互斥。机器输出和 quiet 模式绝不提示;发现可用版本时, | ||
| 调用方必须选择 `--check` 或 `--yes`。 | ||
|
|
||
| ## 设计方案 | ||
|
|
||
| - 入口与分发:`src/cli.rs::Commands::Upgrade` → | ||
| `command::upgrade::execute_safe`,无需仓库 preflight。 | ||
| - `command::upgrade::UpgradeArgs` 仅承载确认策略;签名 manifest 的获取、平台 | ||
| 选择、反回滚状态、安装标记和安装事务由 `internal::upgrade/` 统一负责。 | ||
| - 每次手工检查先验证 manifest 并持久化其反回滚 floors。确认安装前会再次获取和 | ||
| 验证 manifest;控制面变化、暂停或撤销都会拒绝继续使用旧计划。 | ||
| - 安装事务受 `internal::upgrade::lock::UpgradeLock` 保护,下载内容同时验证 size | ||
| 和 sha256,并运行新二进制的 probe;事务或 probe 失败时恢复旧二进制。 | ||
| - 仅安装脚本写入了官方 install marker 的二进制可自升级。源代码构建、改名副本和 | ||
| 不受支持的平台会给出可操作的拒绝结果。 | ||
|
|
||
| ## 当前状态 | ||
|
|
||
| - 公开状态:已公开(`Commands::Upgrade`)。 | ||
| - 用户文档:[docs/commands/upgrade.md](../../commands/upgrade.md)。 | ||
| - 测试:`tests/command/upgrade_cmd_test.rs` 覆盖 CLI/官方安装标记路径; | ||
| `tests/upgrade_auto_test.rs` 和 `tests/upgrade_publish_contract_test.rs` 在 | ||
| `--features test-upgrade` 下覆盖签名、状态转换、安装/回滚与发布契约。 | ||
|
|
||
| ## 维护要求 | ||
|
|
||
| - 改动命令参数或用户可见状态时,同时更新用户文档、此设计文档、 | ||
| `COMPATIBILITY.md` 和 `docs/development/commands/README.md`。 | ||
| - 改动 manifest、反回滚 floor、安装 marker 或事务语义时,必须同步维护 | ||
| `internal::upgrade/` 的跨层测试;不能将验证或持久化错误静默降级。 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -389,16 +389,41 @@ mod unix_impl { | |
| ) | ||
| } | ||
|
|
||
| /// Open the floors micro-lock, retrying only Darwin's transient | ||
| /// `ENOENT` during the concurrent first-create window. Once one | ||
| /// contender creates the regular lock file, the next fd-relative | ||
| /// no-follow open observes and locks that same file. | ||
| fn open_floors_lock_file(&self) -> Result<std::fs::File, InstallDirError> { | ||
| const CREATE_RACE_RETRIES: u32 = 4; | ||
| for attempt in 0..CREATE_RACE_RETRIES { | ||
| match self.openat( | ||
| FLOORS_LOCK_FILE_NAME, | ||
| libc::O_RDWR | libc::O_CREAT, | ||
| 0o600 as libc::c_int, | ||
| ) { | ||
| Ok(file) => return Ok(file), | ||
| Err(InstallDirError::Io { ref detail, .. }) | ||
| if attempt + 1 < CREATE_RACE_RETRIES | ||
| && (detail.contains("No such file") | ||
| || detail.contains("(os error 2)")) => | ||
| { | ||
| std::thread::yield_now(); | ||
| } | ||
| Err(err) => return Err(err), | ||
| } | ||
| } | ||
| Err(InstallDirError::Io { | ||
| name: FLOORS_LOCK_FILE_NAME.to_string(), | ||
| detail: "floors lock creation retry loop ended unexpectedly".into(), | ||
| }) | ||
| } | ||
|
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. Floors lock retry is too weakMedium Severity
Reviewed by Cursor Bugbot for commit ea585f4. Configure here. |
||
|
|
||
| /// Blocking floors micro-lock: kernel-queued, so unlike repeated | ||
| /// non-blocking probes it cannot be starved by a stream of short-lived | ||
| /// holders. Callers bound the wait externally (worker thread + | ||
| /// timeout) because flock itself has none. | ||
| pub fn lock_floors_blocking(&self) -> Result<UpgradeLock, InstallDirError> { | ||
| let file = self.openat( | ||
| FLOORS_LOCK_FILE_NAME, | ||
| libc::O_RDWR | libc::O_CREAT, | ||
| 0o600 as libc::c_int, | ||
| )?; | ||
| let file = self.open_floors_lock_file()?; | ||
| // SAFETY: flock on an owned fd. | ||
| let rc = unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_EX) }; | ||
| if rc != 0 { | ||
|
|
@@ -415,11 +440,7 @@ mod unix_impl { | |
| /// holders only perform one atomic read-merge-write, so contention | ||
| /// clears in milliseconds unless a holder is externally stalled. | ||
| pub fn try_lock_floors(&self) -> Result<Option<UpgradeLock>, InstallDirError> { | ||
| let file = self.openat( | ||
| FLOORS_LOCK_FILE_NAME, | ||
| libc::O_RDWR | libc::O_CREAT, | ||
| 0o600 as libc::c_int, | ||
| )?; | ||
| let file = self.open_floors_lock_file()?; | ||
| // SAFETY: flock on an owned fd. | ||
| let rc = unsafe { libc::flock(file.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) }; | ||
| if rc != 0 { | ||
|
|
||


Uh oh!
There was an error while loading. Please reload this page.