Merge pull request #212 from ikatson/clap-env

[Feature] Add environment variables support to rqbit binary
This commit is contained in:
Igor Katson 2024-08-26 12:16:27 +01:00 committed by GitHub
commit 3042187301
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 58 deletions

40
Cargo.lock generated
View file

@ -456,9 +456,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.4.18"
version = "4.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
dependencies = [
"clap_builder",
"clap_derive",
@ -466,32 +466,32 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.18"
version = "4.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim 0.10.0",
"strsim",
]
[[package]]
name = "clap_complete"
version = "4.4.10"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb745187d7f4d76267b37485a65e0149edd0e91a4cfcdd3f27524ad86cee9f3"
checksum = "531d7959c5bbb6e266cecdd0f20213639c3a5c3e4d615f97db87661745f781ff"
dependencies = [
"clap",
]
[[package]]
name = "clap_derive"
version = "4.4.7"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck 0.4.1",
"heck",
"proc-macro2",
"quote",
"syn",
@ -499,9 +499,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.6.0"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colorchoice"
@ -694,7 +694,7 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
"strsim 0.11.1",
"strsim",
"syn",
]
@ -1121,12 +1121,6 @@ dependencies = [
"num-traits",
]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "heck"
version = "0.5.0"
@ -2982,7 +2976,7 @@ checksum = "1a099220ae541c5db479c6424bdf1b200987934033c2584f79a0e1693601e776"
dependencies = [
"dotenvy",
"either",
"heck 0.5.0",
"heck",
"hex 0.4.3",
"once_cell",
"proc-macro2",
@ -3120,12 +3114,6 @@ dependencies = [
"unicode-properties",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strsim"
version = "0.11.1"

View file

@ -31,8 +31,8 @@ librqbit = { path = "../librqbit", default-features = false, features = [
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
console-subscriber = { version = "0.2", optional = true }
anyhow = "1"
clap = { version = "~4.4", features = ["derive", "deprecated"] }
clap_complete = "~4.4"
clap = { version = "4.5", features = ["derive", "deprecated", "env"] }
clap_complete = "4.5"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
regex = "1"

View file

@ -32,77 +32,99 @@ enum LogLevel {
#[command(version, author, about)]
struct Opts {
/// The console loglevel
#[arg(value_enum, short = 'v')]
#[arg(value_enum, short = 'v', env = "RQBIT_LOG_LEVEL_CONSOLE")]
log_level: Option<LogLevel>,
/// The log filename to also write to in addition to the console.
#[arg(long = "log-file")]
#[arg(long = "log-file", env = "RQBIT_LOG_FILE")]
log_file: Option<String>,
/// The value for RUST_LOG in the log file
#[arg(long = "log-file-rust-log", default_value = "librqbit=debug,info")]
#[arg(
long = "log-file-rust-log",
default_value = "librqbit=debug,info",
env = "RQBIT_LOG_FILE_RUST_LOG"
)]
log_file_rust_log: String,
/// The interval to poll trackers, e.g. 30s.
/// Trackers send the refresh interval when we connect to them. Often this is
/// pretty big, e.g. 30 minutes. This can force a certain value.
#[arg(short = 'i', long = "tracker-refresh-interval", value_parser = parse_duration::parse)]
#[arg(short = 'i', long = "tracker-refresh-interval", value_parser = parse_duration::parse, env="RQBIT_TRACKER_REFRESH_INTERVAL")]
force_tracker_interval: Option<Duration>,
/// The listen address for HTTP API
#[arg(long = "http-api-listen-addr", default_value = "127.0.0.1:3030")]
#[arg(
long = "http-api-listen-addr",
default_value = "127.0.0.1:3030",
env = "RQBIT_HTTP_API_LISTEN_ADDR"
)]
http_api_listen_addr: SocketAddr,
/// Set this flag if you want to use tokio's single threaded runtime.
/// It MAY perform better, but the main purpose is easier debugging, as time
/// profilers work better with this one.
#[arg(short, long)]
#[arg(short, long, env = "RQBIT_SINGLE_THREAD_RUNTIME")]
single_thread_runtime: bool,
#[arg(long = "disable-dht")]
#[arg(long = "disable-dht", env = "RQBIT_DHT_DISABLE")]
disable_dht: bool,
/// Set this to disable DHT reading and storing it's state.
/// For now this is a useful workaround if you want to launch multiple rqbit instances,
/// otherwise DHT port will conflict.
#[arg(long = "disable-dht-persistence")]
#[arg(
long = "disable-dht-persistence",
env = "RQBIT_DHT_PERSISTENCE_DISABLE"
)]
disable_dht_persistence: bool,
/// The connect timeout, e.g. 1s, 1.5s, 100ms etc.
#[arg(long = "peer-connect-timeout", value_parser = parse_duration::parse, default_value="2s")]
#[arg(long = "peer-connect-timeout", value_parser = parse_duration::parse, default_value="2s", env="RQBIT_PEER_CONNECT_TIMEOUT")]
peer_connect_timeout: Duration,
/// The connect timeout, e.g. 1s, 1.5s, 100ms etc.
#[arg(long = "peer-read-write-timeout" , value_parser = parse_duration::parse, default_value="10s")]
#[arg(long = "peer-read-write-timeout" , value_parser = parse_duration::parse, default_value="10s", env="RQBIT_PEER_READ_WRITE_TIMEOUT")]
peer_read_write_timeout: Duration,
/// How many threads to spawn for the executor.
#[arg(short = 't', long)]
#[arg(short = 't', long, env = "RQBIT_RUNTIME_WORKER_THREADS")]
worker_threads: Option<usize>,
// Enable to listen on 0.0.0.0 on TCP for torrent requests.
#[arg(long = "disable-tcp-listen")]
#[arg(long = "disable-tcp-listen", env = "RQBIT_TCP_LISTEN_DISABLE")]
disable_tcp_listen: bool,
/// The minimal port to listen for incoming connections.
#[arg(long = "tcp-min-port", default_value = "4240")]
#[arg(
long = "tcp-min-port",
default_value = "4240",
env = "RQBIT_TCP_LISTEN_MIN_PORT"
)]
tcp_listen_min_port: u16,
/// The maximal port to listen for incoming connections.
#[arg(long = "tcp-max-port", default_value = "4260")]
#[arg(
long = "tcp-max-port",
default_value = "4260",
env = "RQBIT_TCP_LISTEN_MAX_PORT"
)]
tcp_listen_max_port: u16,
/// If set, will try to publish the chosen port through upnp on your router.
#[arg(long = "disable-upnp")]
#[arg(long = "disable-upnp", env = "RQBIT_UPNP_DISABLE_PORT_FORWARD")]
disable_upnp: bool,
/// If set, will run a UPNP Media server and stream all the torrents through it.
/// Should be set to your hostname/IP as seen by your LAN neighbors.
#[arg(long = "upnp-server-hostname")]
#[arg(long = "upnp-server-hostname", env = "RQBIT_UPNP_SERVER_HOSTNAME")]
upnp_server_hostname: Option<String>,
/// UPNP server name that would be displayed on devices in your network.
#[arg(long = "upnp-server-friendly-name")]
#[arg(
long = "upnp-server-friendly-name",
env = "RQBIT_UPNP_SERVER_FRIENDLY_NAME"
)]
upnp_server_friendly_name: Option<String>,
#[command(subcommand)]
@ -111,14 +133,18 @@ struct Opts {
/// How many maximum blocking tokio threads to spawn to process disk reads/writes.
/// This will indicate how many parallel reads/writes can happen at a moment in time.
/// The higher the number, the more the memory usage.
#[arg(long = "max-blocking-threads", default_value = "8")]
#[arg(
long = "max-blocking-threads",
default_value = "8",
env = "RQBIT_RUNTIME_MAX_BLOCKING_THREADS"
)]
max_blocking_threads: u16,
// If you set this to something, all writes to disk will happen in background and be
// buffered in memory up to approximately the given number of megabytes.
//
// Might be useful for slow disks.
#[arg(long = "defer-writes-up-to")]
#[arg(long = "defer-writes-up-to", env = "RQBIT_DEFER_WRITES_UP_TO")]
defer_writes_up_to: Option<usize>,
/// Use mmap (file-backed) for storage. Any advantages are questionable and unproven.
@ -130,11 +156,11 @@ struct Opts {
/// The format is socks5://[username:password]@host:port
///
/// Alternatively, set this as an environment variable RQBIT_SOCKS_PROXY_URL
#[arg(long)]
#[arg(long, env = "RQBIT_SOCKS_PROXY_URL")]
socks_url: Option<String>,
/// How many torrents can be initializing (rehashing) at the same time
#[arg(long, default_value = "5")]
#[arg(long, default_value = "5", env = "RQBIT_CONCURRENT_INIT_LIMIT")]
concurrent_init_limit: usize,
}
@ -142,20 +168,21 @@ struct Opts {
struct ServerStartOptions {
/// The output folder to write to. If not exists, it will be created.
output_folder: String,
#[arg(
long = "disable-persistence",
help = "Disable server persistence. It will not read or write its state to disk."
help = "Disable server persistence. It will not read or write its state to disk.",
env = "RQBIT_SESSION_PERSISTENCE_DISABLE"
)]
/// Disable session persistence.
disable_persistence: bool,
/// The folder to store session data in. By default uses OS specific folder.
#[arg(long = "persistence-config")]
#[arg(long = "persistence-config", env = "RQBIT_SESSION_PERSISTENCE_FOLDER")]
persistence_config: Option<String>,
/// [Experimental] if set, will try to resume quickly after restart and skip checksumming.
#[arg(long = "fastresume")]
#[arg(long = "fastresume", env = "RQBIT_FASTRESUME")]
fastresume: bool,
}
@ -310,10 +337,6 @@ async fn async_main(opts: Opts) -> anyhow::Result<()> {
Err(e) => warn!("failed increasing open file limit: {:#}", e),
};
let socks_url = opts
.socks_url
.or_else(|| std::env::var("RQBIT_SOCKS_PROXY_URL").ok());
let mut sopts = SessionOptions {
disable_dht: opts.disable_dht,
disable_dht_persistence: opts.disable_dht_persistence,
@ -352,7 +375,7 @@ async fn async_main(opts: Opts) -> anyhow::Result<()> {
wrap(FilesystemStorageFactory::default()).boxed()
}
}),
socks_proxy_url: socks_url,
socks_proxy_url: opts.socks_url,
concurrent_init_limit: Some(opts.concurrent_init_limit),
root_span: None,
fastresume: false,