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.unwrap_or(time::Duration::MAX);
33            match addr {
34                Addr::Peer(addr) => control::connect(&mut node, addr.id, addr.addr, timeout)?,
35                Addr::Node(nid) => {
36                    let db = profile.database()?;
37                    let addresses = db
38                        .addresses_of(&nid)?
39                        .into_iter()
40                        .map(|ka| ka.addr)
41                        .collect();
42                    control::connect_many(&mut node, nid, addresses, timeout)?;
43                }
44            }
45        }
46        Command::Config { addresses } => {
47            if addresses {
48                let cfg = node.config()?;
49                for addr in cfg.external_addresses {
50                    term::print(ConnectAddress::from((*profile.id(), addr)).to_string());
51                }
52            } else {
53                control::config(&node)?;
54            }
55        }
56        Command::Db(op) => {
57            commands::db(&profile, op)?;
58        }
59        Command::Debug => {
60            control::debug(&mut node)?;
61        }
62        Command::Sessions => {
63            warning::deprecated("rad node sessions", "rad node status");
64            let sessions = control::sessions(&node)?;
65            if let Some(table) = sessions {
66                table.print();
67            }
68        }
69        Command::Events { timeout, count } => {
70            let count = count.unwrap_or(usize::MAX);
71            let timeout = timeout.unwrap_or(time::Duration::MAX);
72
73            events::run(node, count, timeout)?;
74        }
75        Command::Routing { rid, nid, json } => {
76            let store = profile.database()?;
77            routing::run(&store, rid, nid, json)?;
78        }
79        Command::Logs { lines } => control::logs(lines, Some(time::Duration::MAX), &profile)?,
80        Command::Start {
81            foreground,
82            options,
83            path,
84            verbose,
85        } => {
86            control::start(node, !foreground, verbose, options, &path, &profile)?;
87        }
88        Command::Inventory { nid } => {
89            let nid = nid.as_ref().unwrap_or(profile.id());
90            for rid in profile.routing()?.get_inventory(nid)? {
91                println!("{}", term::format::tertiary(rid));
92            }
93        }
94        Command::Status {
95            only: Some(Only::Nid),
96        } => {
97            if node.is_running() {
98                term::print(term::format::node_id_human(&node.nid()?));
99            } else {
100                process::exit(2);
101            }
102        }
103        Command::Status { only: None } => {
104            control::status(&node, &profile)?;
105        }
106        Command::Stop => {
107            control::stop(node, &profile);
108        }
109    }
110
111    Ok(())
112}