diff options
author | Alex Auvolat <alex@adnab.me> | 2021-05-28 12:36:22 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2021-05-28 14:07:36 +0200 |
commit | b490ebc7f6058719bd22c86fd0db95b09dc027d6 (patch) | |
tree | e1c59ce1c348c2c63e1b2604369997216ef554d1 /src/garage | |
parent | c8aa1eb481c18b1a35ef45d37071ab1af804a382 (diff) | |
download | garage-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.rs | 4 | ||||
-rw-r--r-- | src/garage/cli.rs | 71 |
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); |