Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ coverage/
# Cargo lock for library crates (keep for binary)
# Cargo.lock
CLAUDE.md

# The independent opt-in build owns its artifacts and lockfile.
/rdma/target/
/rdma/Cargo.lock
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "vendor/rustfs-ucx"]
path = vendor/rustfs-ucx
url = git@github.com:rustfs/rustfs-ucx.git
branch = s3-rdma
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
exclude = ["rdma", "vendor/rustfs-ucx"]
resolver = "3"
members = ["crates/cli", "crates/core", "crates/s3"]

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ cd cli
cargo build --release
```

Optional object-data interfaces and the explicit private build are documented
in [RDMA builds](docs/rdma-build.md). The ordinary build requires no private source.

## Quick Start

### Configure Aliases
Expand Down
20 changes: 19 additions & 1 deletion crates/cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use std::io::{IsTerminal, stderr, stdout};

use clap::{Parser, Subcommand, ValueEnum};
use rc_core::config::Defaults;
use rc_core::{ConfigManager, RequestHeader, set_global_request_headers};
use rc_core::{
ConfigManager, DataTransportMode, RequestHeader, set_global_data_transport_mode,
set_global_request_headers,
};

use crate::exit_code::ExitCode;
use crate::output::{Formatter, OutputConfig};
Expand Down Expand Up @@ -90,6 +93,10 @@ fn validate_version_selector(version_id: Option<&str>, rewind: Option<&str>) ->
#[command(after_help = COMPATIBILITY_AFTER_HELP)]
#[command(propagate_version = true)]
pub struct Cli {
/// Object data transport: http, auto, or rdma (requires an installed provider)
#[arg(long, global = true, default_value = "http")]
pub data_transport: DataTransportMode,

/// Output format: auto-detect, human-readable, or JSON
#[arg(long, global = true, value_enum)]
pub format: Option<OutputFormat>,
Expand Down Expand Up @@ -357,6 +364,7 @@ pub enum Commands {

/// Execute the CLI command and return an exit code
pub async fn execute(cli: Cli) -> ExitCode {
set_global_data_transport_mode(cli.data_transport);
set_global_request_headers(cli.request_headers.clone());
let cli_output_options = GlobalOutputOptions::from_cli(&cli);
let defaults = match ConfigManager::new() {
Expand Down Expand Up @@ -564,6 +572,16 @@ pub async fn execute(cli: Cli) -> ExitCode {
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn data_transport_selection_is_explicit_and_http_is_default() {
let cli = Cli::try_parse_from(["rc", "alias", "list"]).expect("default CLI");
assert_eq!(cli.data_transport, DataTransportMode::Http);
let cli = Cli::try_parse_from(["rc", "--data-transport", "rdma", "alias", "list"])
.expect("explicit external data transport");
assert_eq!(cli.data_transport, DataTransportMode::Rdma);
assert!(Cli::try_parse_from(["rc", "--data-transport", "udp", "alias", "list"]).is_err());
}
use clap::Parser;

#[test]
Expand Down
3 changes: 3 additions & 0 deletions crates/cli/src/commands/rb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,9 @@ fn bucket_delete_message(error: &Error, bucket: &str) -> String {

fn exit_code_for_error(error: &Error) -> ExitCode {
match error {
Error::DataTransfer { .. } => {
ExitCode::from_i32(error.exit_code()).unwrap_or(ExitCode::GeneralError)
}
Error::InvalidPath(_) | Error::Config(_) => ExitCode::UsageError,
Error::Network(_) => ExitCode::NetworkError,
Error::Auth(_) => ExitCode::AuthError,
Expand Down
Loading
Loading