cli: Have `init` trigger routing table updates

Before this change, nodes had to be restarted to announce newly
initialized projects.
This commit is contained in:
Alexis Sellier 2023-02-08 16:29:42 +01:00
parent c138cd062c
commit f01735bef6
No known key found for this signature in database
4 changed files with 34 additions and 13 deletions

View File

@ -8,7 +8,7 @@ use anyhow::{anyhow, bail, Context as _};
use radicle::crypto::ssh;
use radicle::git::RefString;
use radicle::node::NodeId;
use radicle::node::{Handle, NodeId};
use crate::git;
use crate::terminal as term;
@ -34,6 +34,7 @@ Options
--set-upstream, -u Setup the upstream of the default branch
--setup-signing Setup the radicle key as a signing key for this repository
--no-confirm Don't ask for confirmation during setup
--no-sync Don't announce the new project to the network
--help Print help
"#,
};
@ -47,6 +48,7 @@ pub struct Options {
pub interactive: Interactive,
pub setup_signing: bool,
pub set_upstream: bool,
pub sync: bool,
}
impl Args for Options {
@ -62,6 +64,7 @@ impl Args for Options {
let mut interactive = Interactive::Yes;
let mut set_upstream = false;
let mut setup_signing = false;
let mut sync = true;
while let Some(arg) = parser.next()? {
match arg {
@ -106,6 +109,12 @@ impl Args for Options {
Long("no-confirm") => {
interactive = Interactive::No;
}
Long("sync") => {
sync = true;
}
Long("no-sync") => {
sync = false;
}
Long("help") => {
return Err(Error::Help.into());
}
@ -125,6 +134,7 @@ impl Args for Options {
interactive,
set_upstream,
setup_signing,
sync,
},
vec![],
))
@ -221,6 +231,14 @@ pub fn init(options: Options, profile: &profile::Profile) -> anyhow::Result<()>
// Setup radicle signing key.
self::setup_signing(profile.id(), &repo, interactive)?;
}
if options.sync {
let spinner = term::spinner("Announcing refs..");
if let Err(e) = radicle::Node::new(profile.socket()).announce_refs(id) {
spinner.error(e);
} else {
spinner.finish();
}
}
term::blank();
term::info!(

View File

@ -35,7 +35,7 @@ impl Spinner {
pub fn error(mut self, msg: impl ToString) {
let msg = msg.to_string();
self.message = format!("{} ({})", self.message, msg);
self.message = format!("{} (error: {})", self.message, msg);
self.set_failed();
}

View File

@ -90,6 +90,7 @@ pub fn seed(dir: &Path) -> Context {
interactive: false.into(),
setup_signing: false,
set_upstream: false,
sync: false,
},
&profile,
)

View File

@ -91,8 +91,6 @@ pub enum Error {
#[error(transparent)]
Storage(#[from] storage::Error),
#[error(transparent)]
Fetch(#[from] storage::FetchError),
#[error(transparent)]
Routing(#[from] routing::Error),
}
@ -701,19 +699,13 @@ where
return Ok(false);
}
if let Err(err) = self.process_inventory(
if let Err(err) = self.sync_inventory(
message.inventory.as_slice(),
*announcer,
&message.timestamp,
) {
error!("Error processing inventory from {}: {}", announcer, err);
if let Error::Fetch(storage::FetchError::Verify(err)) = err {
// Disconnect the peer if it is the signer of this message.
if announcer == relayer {
return Err(session::Error::VerificationFailed(err));
}
}
// There's not much we can do if the peer sending us this message isn't the
// origin of it.
return Ok(false);
@ -722,6 +714,13 @@ where
}
// Process a peer inventory update announcement by (maybe) fetching.
AnnouncementMessage::Refs(message) => {
// We update inventories when receiving ref announcements, as these could come
// from a new repository being initialized.
if let Ok(updated) = self.routing.insert(message.id, *relayer, message.timestamp) {
if updated {
info!(target: "service", "Routing table updated for {} with seed {relayer}", message.id);
}
}
// TODO: Buffer/throttle fetches.
// TODO: Check that we're tracking this user as well.
if self
@ -743,7 +742,8 @@ where
return Ok(true);
} else {
debug!(target: "service",
debug!(
target: "service",
"Ignoring refs announcement from {announcer}: repository {} isn't tracked",
message.id
);
@ -959,7 +959,9 @@ where
}
/// Process a peer inventory announcement by updating our routing table.
fn process_inventory(
/// This function expects the peer's full inventory, and prunes entries that are not in the
/// given inventory.
fn sync_inventory(
&mut self,
inventory: &[Id],
from: NodeId,