aboutsummaryrefslogtreecommitdiff
path: root/src/garage
diff options
context:
space:
mode:
authorAlex Auvolat <lx@deuxfleurs.fr>2025-01-30 12:19:23 +0100
committerAlex Auvolat <lx@deuxfleurs.fr>2025-01-30 12:19:23 +0100
commit819f4f00509a57097d0ee8291e1556829e982e14 (patch)
tree093bea802946c81abd2845c046bad0d25d392624 /src/garage
parent69ddaafc6061d06d277fe772dfaa7fe64ecafcc1 (diff)
downloadgarage-819f4f00509a57097d0ee8291e1556829e982e14.tar.gz
garage-819f4f00509a57097d0ee8291e1556829e982e14.zip
cli: migrate layout remove, apply, revert
Diffstat (limited to 'src/garage')
-rw-r--r--src/garage/cli/layout.rs69
-rw-r--r--src/garage/cli/util.rs21
-rw-r--r--src/garage/cli_v2/layout.rs77
3 files changed, 65 insertions, 102 deletions
diff --git a/src/garage/cli/layout.rs b/src/garage/cli/layout.rs
index d0b62fc7..bb81d144 100644
--- a/src/garage/cli/layout.rs
+++ b/src/garage/cli/layout.rs
@@ -1,7 +1,6 @@
use bytesize::ByteSize;
use format_table::format_table;
-use garage_util::crdt::Crdt;
use garage_util::error::*;
use garage_rpc::layout::*;
@@ -10,33 +9,6 @@ use garage_rpc::*;
use crate::cli::*;
-pub async fn cmd_remove_role(
- rpc_cli: &Endpoint<SystemRpc, ()>,
- rpc_host: NodeID,
- args: RemoveRoleOpt,
-) -> Result<(), Error> {
- let mut layout = fetch_layout(rpc_cli, rpc_host).await?;
-
- let mut roles = layout.current().roles.clone();
- roles.merge(&layout.staging.get().roles);
-
- let deleted_node =
- find_matching_node(roles.items().iter().map(|(id, _, _)| *id), &args.node_id)?;
-
- layout
- .staging
- .get_mut()
- .roles
- .merge(&roles.update_mutator(deleted_node, NodeRoleV(None)));
-
- send_layout(rpc_cli, rpc_host, layout).await?;
-
- println!("Role removal is staged but not yet committed.");
- println!("Use `garage layout show` to view staged role changes,");
- println!("and `garage layout apply` to enact staged changes.");
- Ok(())
-}
-
pub async fn cmd_show_layout(
rpc_cli: &Endpoint<SystemRpc, ()>,
rpc_host: NodeID,
@@ -85,47 +57,6 @@ pub async fn cmd_show_layout(
Ok(())
}
-pub async fn cmd_apply_layout(
- rpc_cli: &Endpoint<SystemRpc, ()>,
- rpc_host: NodeID,
- apply_opt: ApplyLayoutOpt,
-) -> Result<(), Error> {
- let layout = fetch_layout(rpc_cli, rpc_host).await?;
-
- let (layout, msg) = layout.apply_staged_changes(apply_opt.version)?;
- for line in msg.iter() {
- println!("{}", line);
- }
-
- send_layout(rpc_cli, rpc_host, layout).await?;
-
- println!("New cluster layout with updated role assignment has been applied in cluster.");
- println!("Data will now be moved around between nodes accordingly.");
-
- Ok(())
-}
-
-pub async fn cmd_revert_layout(
- rpc_cli: &Endpoint<SystemRpc, ()>,
- rpc_host: NodeID,
- revert_opt: RevertLayoutOpt,
-) -> Result<(), Error> {
- if !revert_opt.yes {
- return Err(Error::Message(
- "Please add the --yes flag to run the layout revert operation".into(),
- ));
- }
-
- let layout = fetch_layout(rpc_cli, rpc_host).await?;
-
- let layout = layout.revert_staged_changes()?;
-
- send_layout(rpc_cli, rpc_host, layout).await?;
-
- println!("All proposed role changes in cluster layout have been canceled.");
- Ok(())
-}
-
pub async fn cmd_config_layout(
rpc_cli: &Endpoint<SystemRpc, ()>,
rpc_host: NodeID,
diff --git a/src/garage/cli/util.rs b/src/garage/cli/util.rs
index 21c14f42..c591cadd 100644
--- a/src/garage/cli/util.rs
+++ b/src/garage/cli/util.rs
@@ -233,27 +233,6 @@ pub fn print_bucket_info(
};
}
-pub fn find_matching_node(
- cand: impl std::iter::Iterator<Item = Uuid>,
- pattern: &str,
-) -> Result<Uuid, Error> {
- let mut candidates = vec![];
- for c in cand {
- if hex::encode(c).starts_with(pattern) && !candidates.contains(&c) {
- candidates.push(c);
- }
- }
- if candidates.len() != 1 {
- Err(Error::Message(format!(
- "{} nodes match '{}'",
- candidates.len(),
- pattern,
- )))
- } else {
- Ok(candidates[0])
- }
-}
-
pub fn print_worker_list(wi: HashMap<usize, WorkerInfo>, wlo: WorkerListOpt) {
let mut wi = wi.into_iter().collect::<Vec<_>>();
wi.sort_by_key(|(tid, info)| {
diff --git a/src/garage/cli_v2/layout.rs b/src/garage/cli_v2/layout.rs
index ccd1886f..8088f019 100644
--- a/src/garage/cli_v2/layout.rs
+++ b/src/garage/cli_v2/layout.rs
@@ -1,5 +1,5 @@
-use bytesize::ByteSize;
-use format_table::format_table;
+//use bytesize::ByteSize;
+//use format_table::format_table;
use garage_util::error::*;
@@ -14,21 +14,14 @@ impl Cli {
pub async fn layout_command_dispatch(&self, cmd: LayoutOperation) -> Result<(), Error> {
match cmd {
LayoutOperation::Assign(assign_opt) => self.cmd_assign_role(assign_opt).await,
+ LayoutOperation::Remove(remove_opt) => self.cmd_remove_role(remove_opt).await,
+ LayoutOperation::Apply(apply_opt) => self.cmd_apply_layout(apply_opt).await,
+ LayoutOperation::Revert(revert_opt) => self.cmd_revert_layout(revert_opt).await,
// TODO
- LayoutOperation::Remove(remove_opt) => {
- cli_v1::cmd_remove_role(&self.system_rpc_endpoint, self.rpc_host, remove_opt).await
- }
LayoutOperation::Show => {
cli_v1::cmd_show_layout(&self.system_rpc_endpoint, self.rpc_host).await
}
- LayoutOperation::Apply(apply_opt) => {
- cli_v1::cmd_apply_layout(&self.system_rpc_endpoint, self.rpc_host, apply_opt).await
- }
- LayoutOperation::Revert(revert_opt) => {
- cli_v1::cmd_revert_layout(&self.system_rpc_endpoint, self.rpc_host, revert_opt)
- .await
- }
LayoutOperation::Config(config_opt) => {
cli_v1::cmd_config_layout(&self.system_rpc_endpoint, self.rpc_host, config_opt)
.await
@@ -116,4 +109,64 @@ impl Cli {
println!("and `garage layout apply` to enact staged changes.");
Ok(())
}
+
+ pub async fn cmd_remove_role(&self, opt: RemoveRoleOpt) -> Result<(), Error> {
+ let status = self.api_request(GetClusterStatusRequest).await?;
+ let layout = self.api_request(GetClusterLayoutRequest).await?;
+
+ let all_node_ids_iter = status
+ .nodes
+ .iter()
+ .map(|x| x.id.as_str())
+ .chain(layout.roles.iter().map(|x| x.id.as_str()));
+
+ let id = find_matching_node(all_node_ids_iter.clone(), &opt.node_id)?;
+
+ let actions = vec![NodeRoleChange {
+ id,
+ action: NodeRoleChangeEnum::Remove { remove: true },
+ }];
+
+ self.api_request(UpdateClusterLayoutRequest(actions))
+ .await?;
+
+ println!("Role removal is staged but not yet committed.");
+ println!("Use `garage layout show` to view staged role changes,");
+ println!("and `garage layout apply` to enact staged changes.");
+ Ok(())
+ }
+
+ pub async fn cmd_apply_layout(&self, apply_opt: ApplyLayoutOpt) -> Result<(), Error> {
+ let missing_version_error = r#"
+Please pass the new layout version number to ensure that you are writing the correct version of the cluster layout.
+To know the correct value of the new layout version, invoke `garage layout show` and review the proposed changes.
+ "#;
+
+ let req = ApplyClusterLayoutRequest {
+ version: apply_opt.version.ok_or_message(missing_version_error)?,
+ };
+ let res = self.api_request(req).await?;
+
+ for line in res.message.iter() {
+ println!("{}", line);
+ }
+
+ println!("New cluster layout with updated role assignment has been applied in cluster.");
+ println!("Data will now be moved around between nodes accordingly.");
+
+ Ok(())
+ }
+
+ pub async fn cmd_revert_layout(&self, revert_opt: RevertLayoutOpt) -> Result<(), Error> {
+ if !revert_opt.yes {
+ return Err(Error::Message(
+ "Please add the --yes flag to run the layout revert operation".into(),
+ ));
+ }
+
+ self.api_request(RevertClusterLayoutRequest).await?;
+
+ println!("All proposed role changes in cluster layout have been canceled.");
+ Ok(())
+ }
}