diff --git a/iroh/src/doc.rs b/iroh/src/doc.rs new file mode 100644 index 0000000000..bc74577923 --- /dev/null +++ b/iroh/src/doc.rs @@ -0,0 +1,83 @@ +pub const IROH_LONG_DESCRIPTION: &str = " +Iroh is a next-generation implementation the Interplanetary File System (IPFS). +IPFS is a networking protocol for exchanging content-addressed blocks of +immutable data. 'content-addressed' means referring to data by the hash of it's +content, which makes the reference both unique and verifiable. These two +properties make it possible to get data from any node in the network that speaks +the IPFS protocol, including IPFS content being served by other implementations +of the protocol. + +For more info see https://iroh.computer/docs"; + +pub const STATUS_LONG_DESCRIPTION: &str = " +status reports the current operational setup of iroh. Use status as a go-to +command for understanding where iroh commands are being processed. different +ops configurations utilize different network and service implementations +under the hood, which can lead to varying performance characteristics. + +Status reports connectivity, which is either offline or online: + + offline: iroh is not connected to any background process, all commands + are one-off, any network connections are closed when a command + completes. Some network duties may be delegated to remote hosts. + + online: iroh has found a long-running process to issue commands to. Any + comand issued will be deletegated to the long-running process as a + remote procedure call + +If iroh is online, status also reports the service configuration of the +long running process, including the health of the configured subsystem(s). +Possible configurations fall into two buckets: + + one: Iroh is running with all services bundled into one single process, + this setup is common in desktop enviornments. + + cloud: Iroh is running with services split into separate processes, which + are speaking to each other via remote procedure calls. + +Use the --watch flag to continually poll for changes. + +Status reports no metrics about the running system aside from current service +health. Instead all metrics are emitted through uniform tracing collection & +reporting, which is intended to be consumed by tools like prometheus and +grafana. For more info on metrics collection, see +https://iroh.computer/docs/metrics"; + +pub const GET_LONG_DESCRIPTION: &str = " +Download file or directory specified by from IPFS into [path]. If +path already exists and is a file then it's overwritten with the new downloaded +file. If path already exists and is a directory, the command fails with an +error. If path already exists, is a file and the downloaded data is a directory, +that's an error. + +By default, the output will be written to the working directory. If no file or +directory name can be derived from the , the output will be written +to the given path's CID. + +If is already present in the iroh store, no network call will +be made."; + +pub const P2P_CONNECT_LONG_DESCRIPTION: &str = " +Attempts to open a new direct connection to a peer address. By default p2p +continulously maintains an open set of peer connections based on requests & +internal hueristics. Connect is useful in situations where it makes sense to +manually force libp2p to dial a known peer. A common example includes when you +know the multiaddr or peer ID of a peer that you would like to exchange data +with. + +The address format is in multiaddr format. For example: + + > iroh p2p connect /ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ + +for more info on multiaddrs see https://iroh.computer/docs/concepts#multiaddr + +If a peer ID is provided, connect first perform a distribtued hash table (DHT) +lookup to learn the address of the given peer ID before dialing."; + +pub const P2P_LOOKUP_LONG_DESCRIPTION: &str = " +Takes as input a peer ID or address and prints the output of the libp2p-identify +protocol. When provided with a peer ID, the address is looked up on the +Network's Distributed Hash Table (DHT) before connecting to the node. When +provided with a multiaddress, the connection is dialed directly. + +Providing no argument will return your local node information."; diff --git a/iroh/src/lib.rs b/iroh/src/lib.rs index 8a2ce9d7c9..5a1c1bab2a 100644 --- a/iroh/src/lib.rs +++ b/iroh/src/lib.rs @@ -1,3 +1,4 @@ +pub mod doc; #[cfg(feature = "testing")] mod fixture; pub mod metrics; diff --git a/iroh/src/p2p.rs b/iroh/src/p2p.rs index a6bddff037..a6a32b3050 100644 --- a/iroh/src/p2p.rs +++ b/iroh/src/p2p.rs @@ -1,11 +1,15 @@ -use std::str::FromStr; - +use crate::doc; use anyhow::{Error, Result}; use clap::{Args, Subcommand}; use iroh_api::{Multiaddr, P2pApi, PeerId, PeerIdOrAddr}; +use std::str::FromStr; #[derive(Args, Debug, Clone)] -#[clap(about = "Manage peer-2-peer networking.")] +#[clap(about = "Peer-2-peer commands")] +#[clap( + after_help = "p2p commands all relate to peer-2-peer connectivity. See subcommands for +additional details." +)] pub struct P2p { #[clap(subcommand)] command: P2pCommands, @@ -13,8 +17,18 @@ pub struct P2p { #[derive(Subcommand, Debug, Clone)] pub enum P2pCommands { + #[clap(about = "Connect to a peer")] + #[clap(after_help = doc::P2P_CONNECT_LONG_DESCRIPTION)] + Connect { + /// Multiaddr or peer ID of a peer to connect to + addr: PeerIdOrAddrArg, + }, #[clap(about = "Retrieve info about a node")] - Lookup { addr: PeerIdOrAddrArg }, + #[clap(after_help = doc::P2P_LOOKUP_LONG_DESCRIPTION)] + Lookup { + /// multiaddress or peer ID + addr: PeerIdOrAddrArg, + }, } #[derive(Debug, Clone)] @@ -35,6 +49,9 @@ impl FromStr for PeerIdOrAddrArg { pub async fn run_command(p2p: &impl P2pApi, cmd: &P2p) -> Result<()> { match &cmd.command { + P2pCommands::Connect { .. } => { + todo!("`iroh p2p connect` is not yet implemented") + } P2pCommands::Lookup { addr } => { let lookup = p2p.lookup(&addr.0).await?; println!("peer id: {}", lookup.peer_id); diff --git a/iroh/src/run.rs b/iroh/src/run.rs index 438397a0f5..ecb2616d0f 100644 --- a/iroh/src/run.rs +++ b/iroh/src/run.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::path::PathBuf; +use crate::doc; #[cfg(feature = "testing")] use crate::fixture::get_fixture_api; use crate::p2p::{run_command as run_p2p_command, P2p}; @@ -10,7 +11,9 @@ use iroh_api::{Api, ApiExt, IpfsPath, Iroh}; use iroh_metrics::config::Config as MetricsConfig; #[derive(Parser, Debug, Clone)] -#[clap(version, about, long_about = None, propagate_version = true)] +#[clap(version, long_about = None, propagate_version = true)] +#[clap(about = "A next generation IPFS implementation: https://iroh.computer")] +#[clap(after_help = doc::IROH_LONG_DESCRIPTION)] pub struct Cli { #[clap(long)] cfg: Option, @@ -33,9 +36,10 @@ impl Cli { enum Commands { // status checks the health of the different processes #[clap(about = "Check the health of the different iroh processes.")] + #[clap(after_help = doc::STATUS_LONG_DESCRIPTION)] Status { #[clap(short, long)] - /// when true, updates the status table whenever a change in a process's status occurs + /// Poll process for changes watch: bool, }, P2p(P2p), @@ -51,6 +55,7 @@ enum Commands { no_wrap: bool, }, #[clap(about = "Fetch IPFS content and write it to disk")] + #[clap(after_help = doc::GET_LONG_DESCRIPTION )] Get { /// CID or CID/with/path/qualifier to get ipfs_path: IpfsPath,