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:
parent
c138cd062c
commit
f01735bef6
|
|
@ -8,7 +8,7 @@ use anyhow::{anyhow, bail, Context as _};
|
||||||
|
|
||||||
use radicle::crypto::ssh;
|
use radicle::crypto::ssh;
|
||||||
use radicle::git::RefString;
|
use radicle::git::RefString;
|
||||||
use radicle::node::NodeId;
|
use radicle::node::{Handle, NodeId};
|
||||||
|
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::terminal as term;
|
use crate::terminal as term;
|
||||||
|
|
@ -34,6 +34,7 @@ Options
|
||||||
--set-upstream, -u Setup the upstream of the default branch
|
--set-upstream, -u Setup the upstream of the default branch
|
||||||
--setup-signing Setup the radicle key as a signing key for this repository
|
--setup-signing Setup the radicle key as a signing key for this repository
|
||||||
--no-confirm Don't ask for confirmation during setup
|
--no-confirm Don't ask for confirmation during setup
|
||||||
|
--no-sync Don't announce the new project to the network
|
||||||
--help Print help
|
--help Print help
|
||||||
"#,
|
"#,
|
||||||
};
|
};
|
||||||
|
|
@ -47,6 +48,7 @@ pub struct Options {
|
||||||
pub interactive: Interactive,
|
pub interactive: Interactive,
|
||||||
pub setup_signing: bool,
|
pub setup_signing: bool,
|
||||||
pub set_upstream: bool,
|
pub set_upstream: bool,
|
||||||
|
pub sync: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Args for Options {
|
impl Args for Options {
|
||||||
|
|
@ -62,6 +64,7 @@ impl Args for Options {
|
||||||
let mut interactive = Interactive::Yes;
|
let mut interactive = Interactive::Yes;
|
||||||
let mut set_upstream = false;
|
let mut set_upstream = false;
|
||||||
let mut setup_signing = false;
|
let mut setup_signing = false;
|
||||||
|
let mut sync = true;
|
||||||
|
|
||||||
while let Some(arg) = parser.next()? {
|
while let Some(arg) = parser.next()? {
|
||||||
match arg {
|
match arg {
|
||||||
|
|
@ -106,6 +109,12 @@ impl Args for Options {
|
||||||
Long("no-confirm") => {
|
Long("no-confirm") => {
|
||||||
interactive = Interactive::No;
|
interactive = Interactive::No;
|
||||||
}
|
}
|
||||||
|
Long("sync") => {
|
||||||
|
sync = true;
|
||||||
|
}
|
||||||
|
Long("no-sync") => {
|
||||||
|
sync = false;
|
||||||
|
}
|
||||||
Long("help") => {
|
Long("help") => {
|
||||||
return Err(Error::Help.into());
|
return Err(Error::Help.into());
|
||||||
}
|
}
|
||||||
|
|
@ -125,6 +134,7 @@ impl Args for Options {
|
||||||
interactive,
|
interactive,
|
||||||
set_upstream,
|
set_upstream,
|
||||||
setup_signing,
|
setup_signing,
|
||||||
|
sync,
|
||||||
},
|
},
|
||||||
vec![],
|
vec![],
|
||||||
))
|
))
|
||||||
|
|
@ -221,6 +231,14 @@ pub fn init(options: Options, profile: &profile::Profile) -> anyhow::Result<()>
|
||||||
// Setup radicle signing key.
|
// Setup radicle signing key.
|
||||||
self::setup_signing(profile.id(), &repo, interactive)?;
|
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::blank();
|
||||||
term::info!(
|
term::info!(
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ impl Spinner {
|
||||||
pub fn error(mut self, msg: impl ToString) {
|
pub fn error(mut self, msg: impl ToString) {
|
||||||
let msg = msg.to_string();
|
let msg = msg.to_string();
|
||||||
|
|
||||||
self.message = format!("{} ({})", self.message, msg);
|
self.message = format!("{} (error: {})", self.message, msg);
|
||||||
self.set_failed();
|
self.set_failed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ pub fn seed(dir: &Path) -> Context {
|
||||||
interactive: false.into(),
|
interactive: false.into(),
|
||||||
setup_signing: false,
|
setup_signing: false,
|
||||||
set_upstream: false,
|
set_upstream: false,
|
||||||
|
sync: false,
|
||||||
},
|
},
|
||||||
&profile,
|
&profile,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,6 @@ pub enum Error {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Storage(#[from] storage::Error),
|
Storage(#[from] storage::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Fetch(#[from] storage::FetchError),
|
|
||||||
#[error(transparent)]
|
|
||||||
Routing(#[from] routing::Error),
|
Routing(#[from] routing::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -701,19 +699,13 @@ where
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = self.process_inventory(
|
if let Err(err) = self.sync_inventory(
|
||||||
message.inventory.as_slice(),
|
message.inventory.as_slice(),
|
||||||
*announcer,
|
*announcer,
|
||||||
&message.timestamp,
|
&message.timestamp,
|
||||||
) {
|
) {
|
||||||
error!("Error processing inventory from {}: {}", announcer, err);
|
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
|
// There's not much we can do if the peer sending us this message isn't the
|
||||||
// origin of it.
|
// origin of it.
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
|
|
@ -722,6 +714,13 @@ where
|
||||||
}
|
}
|
||||||
// Process a peer inventory update announcement by (maybe) fetching.
|
// Process a peer inventory update announcement by (maybe) fetching.
|
||||||
AnnouncementMessage::Refs(message) => {
|
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: Buffer/throttle fetches.
|
||||||
// TODO: Check that we're tracking this user as well.
|
// TODO: Check that we're tracking this user as well.
|
||||||
if self
|
if self
|
||||||
|
|
@ -743,7 +742,8 @@ where
|
||||||
|
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
} else {
|
} else {
|
||||||
debug!(target: "service",
|
debug!(
|
||||||
|
target: "service",
|
||||||
"Ignoring refs announcement from {announcer}: repository {} isn't tracked",
|
"Ignoring refs announcement from {announcer}: repository {} isn't tracked",
|
||||||
message.id
|
message.id
|
||||||
);
|
);
|
||||||
|
|
@ -959,7 +959,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process a peer inventory announcement by updating our routing table.
|
/// 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,
|
&mut self,
|
||||||
inventory: &[Id],
|
inventory: &[Id],
|
||||||
from: NodeId,
|
from: NodeId,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue