my_hypervisor update command to fetch the latest version and updated the installed bin on the system #79

Closed
opened 2026-04-02 10:41:50 +00:00 by mahmoud · 2 comments
Owner
my_hypervisor update 
error: unrecognized subcommand 'update'

Usage: my_hypervisor [OPTIONS] <COMMAND>

For more information, try '--help'.
``` my_hypervisor update error: unrecognized subcommand 'update' Usage: my_hypervisor [OPTIONS] <COMMAND> For more information, try '--help'. ```
rawan self-assigned this 2026-04-05 14:48:38 +00:00
Member

Implementation Spec for Issue #79update Command

Objective

Add a new update subcommand to the CLI that checks the Forgejo releases API for a newer version, downloads the latest binary asset, and replaces the currently installed binary on the system.

Requirements

  1. Query the Forgejo releases API to discover the latest release version and its assets.
  2. Compare the remote version against the compile-time version (CARGO_PKG_VERSION, currently 0.1.4).
  3. If the remote version is newer (or --force is passed), download the appropriate binary asset.
  4. Replace the currently running binary, using doas/sudo if in a privileged path.
  5. Handle errors gracefully: network failures, missing assets, permission errors, already-up-to-date.
  6. Support --check flag (report only, no download) and --force flag (download even when current).

Files to Create

  • crates/my_hypervisor-cli/src/commands/update.rs — The new command implementation

Files to Modify

  • Cargo.toml (workspace root) — Add reqwest and semver to workspace dependencies
  • crates/my_hypervisor-cli/Cargo.toml — Add reqwest and semver as dependencies
  • crates/my_hypervisor-cli/src/cli.rs — Add UpdateArgs struct and Commands::Update variant
  • crates/my_hypervisor-cli/src/commands/mod.rs — Add pub mod update;
  • crates/my_hypervisor-cli/src/main.rs — Wire up Commands::Update in the command dispatch

Implementation Plan

Step 1: Add dependencies (reqwest, semver)

  • Add to workspace Cargo.toml and CLI crate Cargo.toml
  • reqwest with rustls-tls + json + stream features (no OpenSSL, musl-compatible)
  • semver = "1" for robust version comparison

Step 2: Define CLI args and enum variant

  • Add UpdateArgs with --check and --force flags in cli.rs
  • Add Update(UpdateArgs) variant to Commands enum

Step 3: Register module and wire up command

  • Add pub mod update; to commands/mod.rs
  • Add dispatch in main.rs (early-return arm, no VmManager needed)

Step 4: Implement the update command

  • Query Forgejo releases API (?limit=1)
  • Parse tag_name, compare via semver
  • Find correct binary asset (name contains my_hypervisor, not init)
  • Download to tempfile, set executable permissions
  • Replace binary (direct rename, fallback to doas/sudo cp)
  • Report result to user

Step 5: Add unit tests

  • Version comparison logic
  • Asset name matching
  • Clap argument parsing

Acceptance Criteria

  • my_hypervisor update checks and updates when newer version exists
  • my_hypervisor update --check reports availability without downloading
  • my_hypervisor update --force re-downloads even when versions match
  • Uses doas/sudo for privileged binary locations
  • Graceful error messages for all failure modes
  • cargo clippy --workspace -- -D warnings passes
  • cargo fmt --all -- --check passes
  • cargo test --workspace passes

Notes

  • Uses rustls-tls to maintain musl static build compatibility
  • std::env::current_exe() resolves symlinks for correct binary replacement
  • tempfile (already a workspace dep) avoids partial-write corruption
  • Future enhancement: also update my_hypervisor-init binary
## Implementation Spec for Issue #79 — `update` Command ### Objective Add a new `update` subcommand to the CLI that checks the Forgejo releases API for a newer version, downloads the latest binary asset, and replaces the currently installed binary on the system. ### Requirements 1. Query the Forgejo releases API to discover the latest release version and its assets. 2. Compare the remote version against the compile-time version (`CARGO_PKG_VERSION`, currently `0.1.4`). 3. If the remote version is newer (or `--force` is passed), download the appropriate binary asset. 4. Replace the currently running binary, using `doas`/`sudo` if in a privileged path. 5. Handle errors gracefully: network failures, missing assets, permission errors, already-up-to-date. 6. Support `--check` flag (report only, no download) and `--force` flag (download even when current). ### Files to Create - `crates/my_hypervisor-cli/src/commands/update.rs` — The new command implementation ### Files to Modify - `Cargo.toml` (workspace root) — Add `reqwest` and `semver` to workspace dependencies - `crates/my_hypervisor-cli/Cargo.toml` — Add `reqwest` and `semver` as dependencies - `crates/my_hypervisor-cli/src/cli.rs` — Add `UpdateArgs` struct and `Commands::Update` variant - `crates/my_hypervisor-cli/src/commands/mod.rs` — Add `pub mod update;` - `crates/my_hypervisor-cli/src/main.rs` — Wire up `Commands::Update` in the command dispatch ### Implementation Plan #### Step 1: Add dependencies (`reqwest`, `semver`) - Add to workspace `Cargo.toml` and CLI crate `Cargo.toml` - `reqwest` with `rustls-tls` + `json` + `stream` features (no OpenSSL, musl-compatible) - `semver = "1"` for robust version comparison #### Step 2: Define CLI args and enum variant - Add `UpdateArgs` with `--check` and `--force` flags in `cli.rs` - Add `Update(UpdateArgs)` variant to `Commands` enum #### Step 3: Register module and wire up command - Add `pub mod update;` to `commands/mod.rs` - Add dispatch in `main.rs` (early-return arm, no VmManager needed) #### Step 4: Implement the `update` command - Query Forgejo releases API (`?limit=1`) - Parse `tag_name`, compare via `semver` - Find correct binary asset (name contains `my_hypervisor`, not `init`) - Download to tempfile, set executable permissions - Replace binary (direct rename, fallback to `doas`/`sudo` cp) - Report result to user #### Step 5: Add unit tests - Version comparison logic - Asset name matching - Clap argument parsing ### Acceptance Criteria - [ ] `my_hypervisor update` checks and updates when newer version exists - [ ] `my_hypervisor update --check` reports availability without downloading - [ ] `my_hypervisor update --force` re-downloads even when versions match - [ ] Uses `doas`/`sudo` for privileged binary locations - [ ] Graceful error messages for all failure modes - [ ] `cargo clippy --workspace -- -D warnings` passes - [ ] `cargo fmt --all -- --check` passes - [ ] `cargo test --workspace` passes ### Notes - Uses `rustls-tls` to maintain musl static build compatibility - `std::env::current_exe()` resolves symlinks for correct binary replacement - `tempfile` (already a workspace dep) avoids partial-write corruption - Future enhancement: also update `my_hypervisor-init` binary
Member

Test Results

  • Total: 285
  • Passed: 285
  • Failed: 0
  • Clippy: Clean (0 warnings)

All tests pass, including 9 new unit tests for the update command.

Implementation Summary

Files Created

  • crates/my_hypervisor-cli/src/commands/update.rs — New update subcommand implementation with unit tests

Files Modified

  • Cargo.toml — Added reqwest and semver workspace dependencies
  • crates/my_hypervisor-cli/Cargo.toml — Added reqwest, semver, tempfile dependencies
  • crates/my_hypervisor-cli/src/cli.rs — Added UpdateArgs struct and Commands::Update variant
  • crates/my_hypervisor-cli/src/commands/mod.rs — Registered update module
  • crates/my_hypervisor-cli/src/main.rs — Wired up Commands::Update dispatch

Features

  • my_hypervisor update — Checks Forgejo releases API, downloads and replaces binary if newer version available
  • my_hypervisor update --check — Only reports if update is available, no download
  • my_hypervisor update --force — Forces re-download even when versions match
  • Uses doas/sudo fallback for privileged binary locations
  • Uses rustls-tls for musl static build compatibility
  • Uses semver for robust version comparison
  • Uses tempfile to avoid partial-write corruption during download
## Test Results - **Total**: 285 - **Passed**: 285 - **Failed**: 0 - **Clippy**: Clean (0 warnings) All tests pass, including 9 new unit tests for the update command. ## Implementation Summary ### Files Created - `crates/my_hypervisor-cli/src/commands/update.rs` — New `update` subcommand implementation with unit tests ### Files Modified - `Cargo.toml` — Added `reqwest` and `semver` workspace dependencies - `crates/my_hypervisor-cli/Cargo.toml` — Added `reqwest`, `semver`, `tempfile` dependencies - `crates/my_hypervisor-cli/src/cli.rs` — Added `UpdateArgs` struct and `Commands::Update` variant - `crates/my_hypervisor-cli/src/commands/mod.rs` — Registered `update` module - `crates/my_hypervisor-cli/src/main.rs` — Wired up `Commands::Update` dispatch ### Features - `my_hypervisor update` — Checks Forgejo releases API, downloads and replaces binary if newer version available - `my_hypervisor update --check` — Only reports if update is available, no download - `my_hypervisor update --force` — Forces re-download even when versions match - Uses `doas`/`sudo` fallback for privileged binary locations - Uses `rustls-tls` for musl static build compatibility - Uses `semver` for robust version comparison - Uses `tempfile` to avoid partial-write corruption during download
rawan closed this issue 2026-04-07 14:05:24 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
geomind_code/my_hypervisor#79
No description provided.