Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ Once the tracker is running, test it with the UDP tracker client:

```bash
# Default announce (backward compatibility)
cargo run -p torrust-tracker-client --bin udp_tracker_client announce 127.0.0.1:6969 9c38422213e30bff212b30c360d26f9a02136422
cargo run -p torrust-tracker-client --bin tracker_client udp announce 127.0.0.1:6969 9c38422213e30bff212b30c360d26f9a02136422

# Announce with all optional parameters
# NOTE: Use '--peer-id=VALUE' syntax (with equals and single quotes) when peer-id starts with a dash
cargo run -p torrust-tracker-client --bin udp_tracker_client announce \
cargo run -p torrust-tracker-client --bin tracker_client udp announce \
127.0.0.1:6969 443c7602b4fde83d1154d6d9da48808418b181b6 \
--event completed \
--uploaded 1234 \
Expand All @@ -161,7 +161,7 @@ Test the HTTP tracker:

```bash
# Default announce
cargo run --bin http_tracker_client announce http://127.0.0.1:7070 9c38422213e30bff212b30c360d26f9a02136422
cargo run -p torrust-tracker-client --bin tracker_client http announce http://127.0.0.1:7070 9c38422213e30bff212b30c360d26f9a02136422
```

## Notes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,25 @@ INFO_HASH=000620bbc6c52d5a96d98f6c0f1dfa523a40df82
### UDP scrape (preferred public demo)

```bash
cargo run -q -p torrust-tracker-client --bin udp_tracker_client scrape \
cargo run -q -p torrust-tracker-client --bin tracker_client udp scrape \
udp://udp1.torrust-tracker-demo.com:6969/scrape \
"$INFO_HASH" \
--format pretty
--format text
```

### UDP announce (preferred public demo)

```bash
cargo run -q -p torrust-tracker-client --bin udp_tracker_client announce \
cargo run -q -p torrust-tracker-client --bin tracker_client udp announce \
udp://udp1.torrust-tracker-demo.com:6969/announce \
"$INFO_HASH" \
--format compact
--format json
```

### HTTP announce (preferred public demo)

```bash
cargo run -q -p torrust-tracker-client --bin http_tracker_client announce \
cargo run -q -p torrust-tracker-client --bin tracker_client http announce \
https://http1.torrust-tracker-demo.com:443 \
"$INFO_HASH"
```
Expand Down
22 changes: 11 additions & 11 deletions console/tracker-client/docs/features/json-request-input/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ This document describes an alternative to many CLI flags for announce requests.
Instead of passing request parameters only as command-line flags, the client could
accept a full JSON object.

The proposal applies to both clients:
The proposal applies to both protocols under the unified client:

- `http_tracker_client`
- `udp_tracker_client`
- `tracker_client http`
- `tracker_client udp`

## Motivation

Expand All @@ -26,34 +26,34 @@ and future automation.
### 1) JSON file input

```bash
http_tracker_client announce \
--tracker-url http://127.0.0.1:7070 \
tracker_client http announce \
http://127.0.0.1:7070 \
--request-file ./announce.json
```

```bash
udp_tracker_client announce \
--tracker-socket-addr 127.0.0.1:6969 \
tracker_client udp announce \
127.0.0.1:6969 \
--request-file ./announce.json
```

### 2) Inline JSON input

```bash
http_tracker_client announce \
--tracker-url http://127.0.0.1:7070 \
tracker_client http announce \
http://127.0.0.1:7070 \
--request-json '{"info_hash":"443c7602b4fde83d1154d6d9da48808418b181b6","event":"completed"}'
```

### 3) Standard input (stdin)

```bash
echo '{"info_hash":"443c7602b4fde83d1154d6d9da48808418b181b6","event":"completed"}' \
| http_tracker_client announce --tracker-url http://127.0.0.1:7070 --request-stdin
| tracker_client http announce http://127.0.0.1:7070 --request-stdin
```

```bash
cat announce.json | udp_tracker_client announce --tracker-socket-addr 127.0.0.1:6969 --request-stdin
cat announce.json | tracker_client udp announce 127.0.0.1:6969 --request-stdin
```

## Input Shape (Draft)
Expand Down
4 changes: 4 additions & 0 deletions console/tracker-client/src/bin/http_tracker_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ use torrust_tracker_client::console::clients::http::app;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
eprintln!(
"warning: `http_tracker_client` is deprecated and will be removed in a future release. Use `tracker_client http ...` instead."
);

app::run().await
}
4 changes: 4 additions & 0 deletions console/tracker-client/src/bin/tracker_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use torrust_tracker_client::console::clients::checker::app;

#[tokio::main]
async fn main() {
eprintln!(
"warning: `tracker_checker` is deprecated and will be removed in a future release. Use `tracker_client check ...` instead."
);

if let Err(e) = app::run().await {
let (json, exit_code) = e.to_stderr_json_and_exit_code();
eprintln!("{json}");
Expand Down
27 changes: 27 additions & 0 deletions console/tracker-client/src/bin/tracker_client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Unified tracker client binary.
use torrust_tracker_client::console::clients::unified::app;

#[tokio::main]
async fn main() {
if let Err(error) = app::run().await {
match error {
app::Error::Check(err) => {
let (json, exit_code) = err.to_stderr_json_and_exit_code();
eprintln!("{json}");
std::process::exit(exit_code);
}
app::Error::Other(err) => {
let json = serde_json::json!({
"error": {
"kind": "runtime_failure",
"source": "runtime",
"message": err.to_string(),
}
})
.to_string();
eprintln!("{json}");
std::process::exit(1);
}
}
}
}
4 changes: 4 additions & 0 deletions console/tracker-client/src/bin/udp_tracker_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ use torrust_tracker_client::console::clients::udp::app;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
eprintln!(
"warning: `udp_tracker_client` is deprecated and will be removed in a future release. Use `tracker_client udp ...` instead."
);

app::run().await
}
5 changes: 5 additions & 0 deletions console/tracker-client/src/console/clients/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
//! Console clients.
//!
//! `unified` contains the in-progress single-binary implementation for issue #1771.
//! Legacy modules remain available during the deprecation window and are intentionally
//! kept separate so old binaries can stay frozen until the scheduled cleanup removal.
pub mod checker;
pub mod http;
pub mod udp;
pub mod unified;
86 changes: 86 additions & 0 deletions console/tracker-client/src/console/clients/unified/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use clap::{Parser, Subcommand, ValueEnum};
use tracing::level_filters::LevelFilter;

use super::{check, http, udp};
use crate::console::clients::checker::error::AppError;

#[derive(Clone, Copy, Debug, ValueEnum)]
pub enum OutputFormat {
Json,
Text,
}

impl OutputFormat {
#[must_use]
pub fn is_pretty(self) -> bool {
matches!(self, Self::Text)
}
}

#[derive(Debug)]
pub enum Error {
Check(AppError),
Other(anyhow::Error),
}

impl From<anyhow::Error> for Error {
fn from(value: anyhow::Error) -> Self {
Self::Other(value)
}
}

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
#[command(subcommand)]
command: Command,
}

#[derive(Subcommand, Debug)]
enum Command {
/// HTTP tracker commands.
Http {
#[command(subcommand)]
command: http::Command,
},
/// UDP tracker commands.
Udp {
#[command(subcommand)]
command: udp::Command,
},
/// Tracker checker commands and configuration.
Check {
/// Output format for check results.
#[arg(long, value_enum, default_value_t = OutputFormat::Json)]
format: OutputFormat,
/// Arguments passed to the checker implementation.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
},
}

/// # Errors
///
/// Returns an error if command execution fails.
pub async fn run() -> Result<(), Error> {
init_tracing_stdout(LevelFilter::INFO);

let args = Args::parse();

match args.command {
Command::Http { command } => http::run(command).await.map_err(Error::Other)?,
Command::Udp { command } => udp::run(command).await.map_err(Error::Other)?,
Command::Check {
format,
args: checker_args,
} => check::run(checker_args, format).await.map_err(Error::Check)?,
}

Ok(())
}

fn init_tracing_stdout(filter: LevelFilter) {
if tracing_subscriber::fmt().with_max_level(filter).try_init().is_ok() {
tracing::debug!("Logging initialized");
}
}
Loading
Loading