Skip to main content

radicle_cli/commands/
node.rs

1mod args;
2mod commands;
3pub mod control;
4mod events;
5mod logs;
6pub mod routing;
7
8use std::{process, time};
9
10use radicle::node::address::Store as AddressStore;
11use radicle::node::config::ConnectAddress;
12use radicle::node::routing::Store;
13use radicle::node::Handle as _;
14use radicle::node::Node;
15
16use crate::commands::node::args::Only;
17use crate::terminal as term;
18use crate::terminal::Element as _;
19use crate::warning;
20
21pub use args::Args;
22use args::{Addr, Command};
23
24pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
25    let profile = ctx.profile()?;
26    let mut node = Node::new(profile.socket());
27
28    let command = args.command.unwrap_or_default();
29
30    match command {
31        Command::Connect { addr, timeout } => {
32            let timeout = timeout
33                .map(time::Duration::from_secs)
34                .unwrap_or(time::Duration::MAX);
35            match addr {
36                Addr::Peer(addr) => control::connect(&mut node, addr.id, addr.addr, timeout)?,
37                Addr::Node(nid) => {
38                    let db = profile.database()?;
39                    let addresses = db
40                        .addresses_of(&nid)?
41                        .into_iter()
42                        .map(|ka| ka.addr)
43                        .collect();
44                    control::connect_many(&mut node, nid, addresses, timeout)?;
45                }
46            }
47        }
48        Command::Config { addresses } => {
49            if addresses {
50                let cfg = node.config()?;
51                for addr in cfg.external_addresses {
52                    term::print(ConnectAddress::from((*profile.id(), addr)).to_string());
53                }
54            } else {
55                control::config(&node)?;
56            }
57        }
58        Command::Db(op) => {
59            commands::db(&profile, op)?;
60        }
61        Command::Debug => {
62            control::debug(&mut node)?;
63        }
64        Command::Sessions => {
65            warning::deprecated("rad node sessions", "rad node status");
66            let sessions = control::sessions(&node)?;
67            if let Some(table) = sessions {
68                table.print();
69            }
70        }
71        Command::Events { timeout, count } => {
72            let count = count.unwrap_or(usize::MAX);
73            let timeout = timeout
74                .map(time::Duration::from_secs)
75                .unwrap_or(time::Duration::MAX);
76
77            events::run(node, count, timeout)?;
78        }
79        Command::Routing { rid, nid, json } => {
80            let store = profile.database()?;
81            routing::run(&store, rid, nid, json)?;
82        }
83        Command::Logs { lines } => control::logs(lines, Some(time::Duration::MAX), &profile)?,
84        Command::Start {
85            foreground,
86            options,
87            path,
88            verbose,
89        } => {
90            control::start(node, !foreground, verbose, options, &path, &profile)?;
91        }
92        Command::Inventory { nid } => {
93            let nid = nid.as_ref().unwrap_or(profile.id());
94            for rid in profile.routing()?.get_inventory(nid)? {
95                println!("{}", term::format::tertiary(rid));
96            }
97        }
98        Command::Status {
99            only: Some(Only::Nid),
100        } => {
101            if node.is_running() {
102                term::print(term::format::node_id_human(&node.nid()?));
103            } else {
104                process::exit(2);
105            }
106        }
107        Command::Status { only: None } => {
108            control::status(&node, &profile)?;
109        }
110        Command::Stop => {
111            control::stop(node, &profile);
112        }
113    }
114
115    Ok(())
116}