Skip to content

feat(iii-worker): add --force, reinstall, and clear commands#1442

Merged
andersonleal merged 5 commits intomainfrom
feat/worker-clean-install
Apr 9, 2026
Merged

feat(iii-worker): add --force, reinstall, and clear commands#1442
andersonleal merged 5 commits intomainfrom
feat/worker-clean-install

Conversation

@andersonleal
Copy link
Copy Markdown
Contributor

@andersonleal andersonleal commented Apr 8, 2026

Summary

  • Add --force / -f flag to iii worker add to re-download worker artifacts (binary or OCI)
  • Add --reset-config flag to also reset config.yaml entry to registry defaults (requires --force)
  • Add iii worker reinstall as convenience alias for add --force
  • Add iii worker clear [name] [--yes] to wipe downloaded artifacts from ~/.iii/

New CLI surface

iii worker add <name[@version]> --force [-f] [--reset-config]
iii worker reinstall <name[@version]> [--reset-config]
iii worker clear [name] [--yes/-y]

Safety guards

  • Running workers are detected via PID liveness checks and blocked from deletion
  • Worker names validated before any filesystem operations (path traversal prevention)
  • clear without a name requires confirmation prompt (skip with --yes)
  • OCI image dirs of running workers are protected during clear-all
  • Directory entries canonicalized to prevent symlink-based deletion outside ~/.iii/

Design

  • Shared AddArgs struct via #[command(flatten)] keeps Add/Reinstall in sync
  • image_cache_dir() centralizes OCI SHA-256 hash path computation (was duplicated 3x)
  • handle_managed_clear is synchronous (no fake async)
  • confirm_clear() extracted for testability

Test plan

  • 168 unit tests passing (cargo test -p iii-worker --lib)
  • iii worker add --help shows --force and --reset-config
  • iii worker reinstall --help shows shared args via flatten
  • iii worker clear --help shows [WORKER] and --yes
  • iii worker clear --yes with no artifacts prints "Nothing to clear."
  • --reset-config requires --force (clap validation)
  • Manual: iii worker add pdfkit --force re-downloads binary
  • Manual: iii worker reinstall pdfkit equivalent behavior
  • Manual: iii worker clear pdfkit removes artifacts, keeps config

Summary by CodeRabbit

  • New Features

    • add gains --force/-f to force re-downloads and --reset-config to restore defaults.
    • New reinstall command that mirrors add --force and supports --reset-config.
    • New clear command to remove local artifacts (all or single worker) with --yes/-y to skip confirmation.
  • Tests

    • Expanded coverage for add/reinstall/clear parsing and behaviors, artifact/cache handling, running-worker protections, deletion outcomes, and confirmation prompts.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
iii-website Ready Ready Preview, Comment Apr 8, 2026 11:06pm
motia-docs Ready Ready Preview, Comment Apr 8, 2026 11:06pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

Introduces a shared AddArgs for add/reinstall, adds --force to add, and new reinstall and clear subcommands. Extends handle_managed_add with force/reset_config, adds handle_managed_clear, running-worker checks, artifact deletion and OCI cache helpers, and updates tests and CLI routing.

Changes

Cohort / File(s) Summary
CLI defs & exports
crates/iii-worker/src/cli/app.rs, crates/iii-worker/src/lib.rs
Add pub struct AddArgs and use #[command(flatten)]; Commands::Add now { args: AddArgs, force: bool }; add Commands::Reinstall and Commands::Clear; re-export AddArgs.
Managed handlers & helpers
crates/iii-worker/src/cli/managed.rs
Extend handle_managed_add(..., force, reset_config); add handle_managed_clear, is_worker_running, delete_worker_artifacts, image_cache_dir, dir_size, confirmation flow, running-worker/OCI protections, and unit tests; centralize OCI cache hashing.
Command routing / runtime
crates/iii-worker/src/main.rs
Update match arms to Commands::Add { args, force }; add Reinstall { args } (calls add with force=true) and Clear { worker_name, yes } (calls handle_managed_clear).
Tests & integration
crates/iii-worker/tests/*, crates/iii-worker/tests/config_file_integration.rs, crates/iii-worker/tests/worker_integration.rs
Update tests to new handle_managed_add signature; add tests for --force and --reset-config behaviors, clear behavior, and CLI parsing for new flags/subcommands.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI (user)
    participant Main as main.rs
    participant Managed as managed.rs
    participant FS as File System

    CLI->>Main: invoke `iii-worker add|reinstall|clear ...`
    Main->>Managed: call handler (handle_managed_add / handle_managed_clear) with args
    alt add / reinstall
        Managed->>Managed: parse/validate worker name (OCI vs plain)
        Managed->>Managed: check running state (is_worker_running)
        alt force
            Managed->>FS: remove existing artifacts (delete_worker_artifacts)
        end
        Managed->>FS: pull/cache artifacts (image_cache_dir / OCI pull)
        FS-->>Managed: artifact result
    else clear
        Managed->>Managed: if single -> validate -> confirm_clear (unless --yes)
        Managed->>Managed: collect running OCI hashes to protect
        Managed->>FS: delete selected artifacts or all
        FS-->>Managed: freed size
    end
    Managed-->>Main: return status code
    Main-->>CLI: exit with status
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • sergiofilhowz
  • ytallo

Poem

🐰 I hopped through code with tidy paws,

Shared args, a force, and clearer laws,
Reinstall, clear — the cache I comb,
Configs reset, artifacts home,
A jaunty hop — this CLI awes!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main additions to the PR: three new features (--force flag, reinstall command, and clear command) for the iii-worker CLI.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/worker-clean-install

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

sergiofilhowz
sergiofilhowz previously approved these changes Apr 8, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
crates/iii-worker/src/cli/app.rs (1)

31-33: Consider enforcing --reset-config requires --force at the clap level.

The help text states --reset-config requires --force on add, but this constraint is enforced at runtime in handle_managed_add rather than via clap's requires attribute. The current approach works correctly, but clap-level validation would provide clearer error messages directly from the argument parser.

♻️ Optional: Add clap constraint
     /// Reset config: also remove config.yaml entry before re-adding (requires --force on add)
-    #[arg(long)]
+    #[arg(long, requires = "force")]
     pub reset_config: bool,

Note: This would require force to be part of AddArgs or use a different approach since force is defined outside the flattened struct. The current runtime enforcement is acceptable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/iii-worker/src/cli/app.rs` around lines 31 - 33, The CLI currently
enforces the `--reset-config` + `--force` constraint at runtime in
`handle_managed_add`; instead add a clap-level requirement so parsing fails with
a clear message: update the `reset_config` arg declaration (the field
`reset_config` in the struct) to include a clap `requires = "force"` (or
`requires_if` variant) or alternatively move the `force` flag into the same
flattened `AddArgs` struct so `requires` can reference it; keep
`handle_managed_add` validation as a fallback but rely on clap's `requires`
between `reset_config` and `force` for immediate parser-level validation.
crates/iii-worker/src/cli/managed.rs (1)

458-461: Inconsistent error handling: deletion failures silently ignored.

Lines 459 and 488 use let _ = std::fs::remove_dir_all(...) which silently discards errors. This is inconsistent with delete_worker_artifacts (lines 557-575) which emits warnings on failure. Users may be confused if the reported "freed" size doesn't match actual space reclaimed due to permission issues.

♻️ Proposed fix: warn on deletion failures
-                let _ = std::fs::remove_dir_all(entry.path());
+                if let Err(e) = std::fs::remove_dir_all(entry.path()) {
+                    eprintln!(
+                        "  {} Failed to remove {}: {}",
+                        "warning:".yellow(),
+                        entry.path().display(),
+                        e
+                    );
+                }
                 worker_count += 1;

Apply similar change at line 488 for image deletion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/iii-worker/src/cli/managed.rs` around lines 458 - 461, The deletion
calls currently ignore errors (e.g., `let _ =
std::fs::remove_dir_all(entry.path())`) causing mismatched freed-size reporting;
update these to handle the Result and emit a warning on failure (same style as
`delete_worker_artifacts`), e.g., check the Result from
`std::fs::remove_dir_all(...)` and call the project's logger (or `warn!`) with
context including the path and the error; apply this change at the directory
deletion site (where `dir_size(&entry.path())` and `worker_count` are used) and
also to the image deletion call mentioned for line ~488 so both deletion paths
consistently warn on errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/iii-worker/src/cli/managed.rs`:
- Around line 409-415: The prompt in confirm_clear() may not appear because
eprint! doesn't flush stderr; update confirm_clear to explicitly flush stderr
after the eprint! call (use std::io::stderr().flush() or equivalent) before
calling std::io::stdin().read_line so the user sees "Continue? [y/N]" prior to
input being read; handle any flush error as appropriate (propagate/log or
ignore) to avoid blocking behavior.
- Around line 502-509: The warning message prints the OCI image identifier from
the skipped list as the suggested stop target, which is invalid; update the loop
that iterates over skipped to detect when an entry is an OCI image (e.g.,
matches image/hash pattern) and lookup the corresponding worker name (use or add
a helper like find_running_by_image(image_id) or
get_worker_name_from_image(image_id)) and then print that worker name in the
stop suggestion; keep the existing message for entries that already are worker
names. Ensure you update the loop over skipped to call the lookup helper and
fall back to the original entry if no worker name is found so the suggestion is
always a valid worker name.

---

Nitpick comments:
In `@crates/iii-worker/src/cli/app.rs`:
- Around line 31-33: The CLI currently enforces the `--reset-config` + `--force`
constraint at runtime in `handle_managed_add`; instead add a clap-level
requirement so parsing fails with a clear message: update the `reset_config` arg
declaration (the field `reset_config` in the struct) to include a clap `requires
= "force"` (or `requires_if` variant) or alternatively move the `force` flag
into the same flattened `AddArgs` struct so `requires` can reference it; keep
`handle_managed_add` validation as a fallback but rely on clap's `requires`
between `reset_config` and `force` for immediate parser-level validation.

In `@crates/iii-worker/src/cli/managed.rs`:
- Around line 458-461: The deletion calls currently ignore errors (e.g., `let _
= std::fs::remove_dir_all(entry.path())`) causing mismatched freed-size
reporting; update these to handle the Result and emit a warning on failure (same
style as `delete_worker_artifacts`), e.g., check the Result from
`std::fs::remove_dir_all(...)` and call the project's logger (or `warn!`) with
context including the path and the error; apply this change at the directory
deletion site (where `dir_size(&entry.path())` and `worker_count` are used) and
also to the image deletion call mentioned for line ~488 so both deletion paths
consistently warn on errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: dba303ae-0470-4942-ad37-ca4ab83619b1

📥 Commits

Reviewing files that changed from the base of the PR and between f39b82c and 2ee1c35.

📒 Files selected for processing (4)
  • crates/iii-worker/src/cli/app.rs
  • crates/iii-worker/src/cli/managed.rs
  • crates/iii-worker/src/lib.rs
  • crates/iii-worker/src/main.rs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/iii-worker/tests/worker_integration.rs (1)

59-64: Add default assertion for reset_config in this Add parsing test.

At Line 59-64, this test validates defaults but skips args.reset_config. Adding it will better lock down the new flattened AddArgs behavior.

Proposed test tweak
         Commands::Add { args, force } => {
             assert_eq!(args.worker_name, "ghcr.io/iii-hq/node:latest");
             assert_eq!(args.runtime, "libkrun");
             assert_eq!(args.address, "localhost");
             assert_eq!(args.port, DEFAULT_PORT);
+            assert!(!args.reset_config);
             assert!(!force);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/iii-worker/tests/worker_integration.rs` around lines 59 - 64, The test
for Commands::Add needs an assertion for the new flattened AddArgs.reset_config
default; update the Add branch in the worker_integration.rs test (where it
checks args.worker_name, args.runtime, args.address, args.port, and force) to
also assert the expected default value of args.reset_config (likely false) so
the parsing behavior of AddArgs is locked down; modify the assertion block that
handles Commands::Add to include assert_eq!(args.reset_config,
<expected_default>) referencing the args.reset_config field on the AddArgs
instance.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/iii-worker/tests/worker_integration.rs`:
- Around line 59-64: The test for Commands::Add needs an assertion for the new
flattened AddArgs.reset_config default; update the Add branch in the
worker_integration.rs test (where it checks args.worker_name, args.runtime,
args.address, args.port, and force) to also assert the expected default value of
args.reset_config (likely false) so the parsing behavior of AddArgs is locked
down; modify the assertion block that handles Commands::Add to include
assert_eq!(args.reset_config, <expected_default>) referencing the
args.reset_config field on the AddArgs instance.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fe777b34-8443-4ef3-b147-b84828e81f1b

📥 Commits

Reviewing files that changed from the base of the PR and between 2ee1c35 and 52500f9.

📒 Files selected for processing (2)
  • crates/iii-worker/tests/config_file_integration.rs
  • crates/iii-worker/tests/worker_integration.rs

Add CLI commands for re-downloading and cleaning up worker artifacts:

- `iii worker add --force` / `-f`: delete local artifacts before re-downloading
- `iii worker add --force --reset-config`: also reset config.yaml to defaults
- `iii worker reinstall <name>`: alias for `add --force`
- `iii worker clear [name] [--yes]`: wipe downloaded binaries and OCI images

Implementation details:
- Shared `AddArgs` struct via `#[command(flatten)]` for Add/Reinstall
- `is_worker_running()` helper guards against clearing active workers
- `delete_worker_artifacts()` handles both binary dirs and OCI image dirs
- `image_cache_dir()` centralizes SHA-256 hash computation for OCI paths
- `clear_all_workers` validates dir names and canonicalizes paths for safety
- OCI references bypass worker name validation in --force path
- Running OCI workers protected during clear-all via hash set lookup
- Confirmation prompt for `clear` without `--yes`; extracted for testability
…signature

Update tests to match AddArgs flatten refactor and new force/reset_config
parameters on handle_managed_add.
… clear

Unit tests (managed.rs):
- delete_worker_artifacts: file removal, nested dir removal
- is_worker_running: invalid PID content, empty PID file
- image_cache_dir: deterministic hash, path structure

Integration tests (worker_integration.rs):
- CLI parsing for --force, -f, --reset-config, reinstall, clear, --yes/-y

Integration tests (config_file_integration.rs):
- handle_managed_add with force=true on builtins
- handle_managed_add with force+reset_config clears user overrides
- handle_managed_add with force preserves config when no reset
- handle_managed_clear: single worker, invalid name, clear-all
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/iii-worker/src/main.rs (1)

22-42: Deduplicate the forced add path and keep registry reuse in one place.

add --force and reinstall now own the same per-worker loop. That makes the two entrypoints easy to drift apart, and both currently bypass the dedicated multi-worker path by calling handle_managed_add(..., None, ...) for every worker. I'd pull this into one helper so behavior stays aligned, and so a shared cached_registry can be threaded through if that parameter is meant to amortize repeated lookups.

Also applies to: 47-63

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/iii-worker/src/main.rs` around lines 22 - 42, The forced per-worker
loop in the Commands::Add branch duplicates logic used by the reinstall path and
bypasses handle_managed_add_many; refactor by extracting a single helper (e.g.,
managed_add_many_with_options) that takes &Vec<String>, force flag,
reset_config, and an optional cached_registry and implements the per-worker
loop, calling iii_worker::cli::managed::handle_managed_add for each name; update
both the Add --force branch and the reinstall entrypoint to call this helper so
behavior stays aligned and the shared cached_registry is created once and
threaded through to amortize lookups.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/iii-worker/src/main.rs`:
- Around line 22-42: The forced per-worker loop in the Commands::Add branch
duplicates logic used by the reinstall path and bypasses
handle_managed_add_many; refactor by extracting a single helper (e.g.,
managed_add_many_with_options) that takes &Vec<String>, force flag,
reset_config, and an optional cached_registry and implements the per-worker
loop, calling iii_worker::cli::managed::handle_managed_add for each name; update
both the Add --force branch and the reinstall entrypoint to call this helper so
behavior stays aligned and the shared cached_registry is created once and
threaded through to amortize lookups.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 48648c91-057b-4a39-9fc4-ef7b0aa24d81

📥 Commits

Reviewing files that changed from the base of the PR and between f90d6ba and 459414e.

📒 Files selected for processing (6)
  • crates/iii-worker/src/cli/app.rs
  • crates/iii-worker/src/cli/managed.rs
  • crates/iii-worker/src/lib.rs
  • crates/iii-worker/src/main.rs
  • crates/iii-worker/tests/config_file_integration.rs
  • crates/iii-worker/tests/worker_integration.rs
✅ Files skipped from review due to trivial changes (1)
  • crates/iii-worker/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/iii-worker/tests/config_file_integration.rs
  • crates/iii-worker/tests/worker_integration.rs
  • crates/iii-worker/src/cli/managed.rs
  • crates/iii-worker/src/cli/app.rs

@andersonleal andersonleal merged commit 8921efa into main Apr 9, 2026
26 checks passed
@andersonleal andersonleal deleted the feat/worker-clean-install branch April 9, 2026 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants