aboutsummaryrefslogtreecommitdiff
path: root/src/garage
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2021-05-28 12:36:22 +0200
committerAlex Auvolat <alex@adnab.me>2021-05-28 14:07:36 +0200
commitb490ebc7f6058719bd22c86fd0db95b09dc027d6 (patch)
treee1c59ce1c348c2c63e1b2604369997216ef554d1 /src/garage
parentc8aa1eb481c18b1a35ef45d37071ab1af804a382 (diff)
downloadgarage-b490ebc7f6058719bd22c86fd0db95b09dc027d6.tar.gz
garage-b490ebc7f6058719bd22c86fd0db95b09dc027d6.zip
Many improvements on ring/replication and its configuration:
- Explicit "replication_mode" configuration parameters that takes either "none", "2" or "3" as values, instead of letting user configure replication factor themselves. These are presets whose corresponding replication/quorum values can be found in replication/mode.rs - Explicit support for single-node and two-node deployments (number of nodes must be at least "replication_mode", with "none" we can have only one node) - Ring is now stored much more compactly with 256*8 + n*32 bytes, instead of 256*32 bytes - Support for gateway-only nodes that do not store data (these nodes still need a metadata_directory to store the list of bucket and keys since those are stored on all nodes; it also technically needs a data_directory to start but it will stay empty unless we have bugs)
Diffstat (limited to 'src/garage')
-rw-r--r--src/garage/admin_rpc.rs4
-rw-r--r--src/garage/cli.rs71
2 files changed, 54 insertions, 21 deletions
diff --git a/src/garage/admin_rpc.rs b/src/garage/admin_rpc.rs
index f2d11bb3..b1538a30 100644
--- a/src/garage/admin_rpc.rs
+++ b/src/garage/admin_rpc.rs
@@ -430,8 +430,8 @@ impl AdminRpcHandler {
// Gather ring statistics
let ring = self.garage.system.ring.borrow().clone();
let mut ring_nodes = HashMap::new();
- for r in ring.ring.iter() {
- for n in r.nodes.iter() {
+ for (_i, loc) in ring.partitions().iter() {
+ for n in ring.get_nodes(loc, ring.replication_factor).iter() {
if !ring_nodes.contains_key(n) {
ring_nodes.insert(*n, 0usize);
}
diff --git a/src/garage/cli.rs b/src/garage/cli.rs
index bfe7e08e..42cc657f 100644
--- a/src/garage/cli.rs
+++ b/src/garage/cli.rs
@@ -80,6 +80,10 @@ pub struct ConfigureNodeOpt {
#[structopt(short = "c", long = "capacity")]
capacity: Option<u32>,
+ /// Gateway-only node
+ #[structopt(short = "g", long = "gateway")]
+ gateway: bool,
+
/// Optional node tag
#[structopt(short = "t", long = "tag")]
tag: Option<String>,
@@ -339,7 +343,12 @@ pub async fn cmd_status(
if let Some(cfg) = config.members.get(&adv.id) {
println!(
"{:?}\t{}\t{}\t[{}]\t{}\t{}",
- adv.id, adv.state_info.hostname, adv.addr, cfg.tag, cfg.datacenter, cfg.capacity
+ adv.id,
+ adv.state_info.hostname,
+ adv.addr,
+ cfg.tag,
+ cfg.datacenter,
+ cfg.capacity_string()
);
} else {
println!(
@@ -366,7 +375,7 @@ pub async fn cmd_status(
adv.addr,
cfg.tag,
cfg.datacenter,
- cfg.capacity,
+ cfg.capacity_string(),
(now_msec() - adv.last_seen) / 1000,
);
}
@@ -375,7 +384,10 @@ pub async fn cmd_status(
if !status.iter().any(|x| x.id == *id) {
println!(
"{:?}\t{}\t{}\t{}\tnever seen",
- id, cfg.tag, cfg.datacenter, cfg.capacity
+ id,
+ cfg.tag,
+ cfg.datacenter,
+ cfg.capacity_string(),
);
}
}
@@ -438,23 +450,44 @@ pub async fn cmd_configure(
}
}
+ if args.capacity.is_some() && args.gateway {
+ return Err(Error::Message(
+ "-c and -g are mutually exclusive, please configure node either with c>0 to act as a storage node or with -g to act as a gateway node".into()));
+ }
+ if args.capacity == Some(0) {
+ return Err(Error::Message("Invalid capacity value: 0".into()));
+ }
+
let new_entry = match config.members.get(&added_node) {
- None => NetworkConfigEntry {
- datacenter: args
- .datacenter
- .expect("Please specifiy a datacenter with the -d flag"),
- capacity: args
- .capacity
- .expect("Please specifiy a capacity with the -c flag"),
- tag: args.tag.unwrap_or_default(),
- },
- Some(old) => NetworkConfigEntry {
- datacenter: args
- .datacenter
- .unwrap_or_else(|| old.datacenter.to_string()),
- capacity: args.capacity.unwrap_or(old.capacity),
- tag: args.tag.unwrap_or_else(|| old.tag.to_string()),
- },
+ None => {
+ let capacity = match args.capacity {
+ Some(c) => Some(c),
+ None if args.gateway => None,
+ _ => return Err(Error::Message(
+ "Please specify a capacity with the -c flag, or set node explicitly as gateway with -g".into())),
+ };
+ NetworkConfigEntry {
+ datacenter: args
+ .datacenter
+ .expect("Please specifiy a datacenter with the -d flag"),
+ capacity,
+ tag: args.tag.unwrap_or_default(),
+ }
+ }
+ Some(old) => {
+ let capacity = match args.capacity {
+ Some(c) => Some(c),
+ None if args.gateway => None,
+ _ => old.capacity,
+ };
+ NetworkConfigEntry {
+ datacenter: args
+ .datacenter
+ .unwrap_or_else(|| old.datacenter.to_string()),
+ capacity,
+ tag: args.tag.unwrap_or_else(|| old.tag.to_string()),
+ }
+ }
};
config.members.insert(added_node, new_entry);