Skip to content

Commit d93c7e9

Browse files
authored
Add support for Arbiter pools (#323)
* Add support for Arbiter pools Signed-off-by: Shree Vatsa N <[email protected]>
1 parent 863e621 commit d93c7e9

File tree

6 files changed

+87
-24
lines changed

6 files changed

+87
-24
lines changed

mgr/shard.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ shards:
66

77
crinja:
88
git: https://github.com/straight-shoota/crinja.git
9-
version: 0.8.0
9+
version: 0.8.1
1010

1111
db:
1212
git: https://github.com/crystal-lang/crystal-db.git
@@ -22,7 +22,7 @@ shards:
2222

2323
kemal:
2424
git: https://github.com/kemalcr/kemal.git
25-
version: 1.3.0
25+
version: 1.4.0
2626

2727
moana_types:
2828
path: ../types
@@ -38,7 +38,7 @@ shards:
3838

3939
volgen:
4040
git: https://github.com/kadalu/volgen.git
41-
version: 0.3.1
41+
version: 0.4.1
4242

4343
xattr:
4444
git: https://github.com/aravindavk/xattr-crystal.git

mgr/src/cmds/pool_create_parser.cr

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ module PoolRequestParser
178178
storage_units["replica"].size,
179179
storage_units["mirror"].size
180180
)
181+
elsif storage_units["arbiter"].size == 3
182+
grp_storage_units = storage_units["arbiter"]
183+
dist_group.replica_count = 3
184+
dist_group.arbiter_count = 1
181185
elsif storage_units["disperse"].size > 0 ||
182186
storage_units["data"].size > 0
183187
grp_storage_units = storage_units["disperse"] +
@@ -284,30 +288,49 @@ module PoolRequestParser
284288
req
285289
end
286290

287-
# Validate the Pool create request after parsing
288291
def self.validate(req)
292+
validate_pool_name(req)
293+
validate_storage_units(req.distribute_groups)
294+
end
295+
296+
def self.validate_pool_name(req)
297+
# TODO: Pool name validations
289298
raise InvalidPoolRequest.new("Pool name not specified (Example: mypool)") if req.name == ""
290299
raise InvalidPoolRequest.new("Atleast one Storage unit is required") if req.distribute_groups.size == 0
300+
end
291301

292-
# TODO: Pool name validations
302+
def self.validate_storage_units(distribute_groups)
303+
distribute_groups.each do |dist_grp|
304+
validate_storage_units_match_replica_count(dist_grp)
305+
validate_storage_units_match_disperse_count(dist_grp)
306+
validate_storage_units_node_names(dist_grp.storage_units)
307+
end
308+
end
293309

294-
req.distribute_groups.each do |dist_grp|
295-
if dist_grp.replica_count > 0 && dist_grp.storage_units.size != dist_grp.replica_count
296-
raise InvalidPoolRequest.new(
297-
"Number of Storage units not matching #{dist_grp.replica_keyword} count"
298-
)
299-
end
300-
if dist_grp.disperse_count > 0 && dist_grp.storage_units.size != dist_grp.disperse_count
301-
raise InvalidPoolRequest.new(
302-
"Number of Storage units not matching disperse count"
303-
)
304-
end
310+
def self.validate_storage_units_match_replica_count(dist_grp)
311+
replica_arbiter_dist_grp_size = dist_grp.replica_count
312+
replica_arbiter_dist_grp_size += 1 if dist_grp.arbiter_count > 0 && dist_grp.replica_count == 2
305313

306-
dist_grp.storage_units.each do |storage_unit|
307-
msg = storage_unit.port > 0 ? "#{storage_unit.port}:" : ""
308-
msg += storage_unit.path
309-
raise InvalidPoolRequest.new("Node name is not specified for #{msg}") if storage_unit.node.name == ""
310-
end
314+
if dist_grp.replica_count > 0 && dist_grp.storage_units.size != replica_arbiter_dist_grp_size
315+
raise InvalidPoolRequest.new(
316+
"Number of Storage units not matching #{dist_grp.replica_keyword} count"
317+
)
318+
end
319+
end
320+
321+
def self.validate_storage_units_match_disperse_count(dist_grp)
322+
if dist_grp.disperse_count > 0 && dist_grp.storage_units.size != dist_grp.disperse_count
323+
raise InvalidPoolRequest.new(
324+
"Number of Storage units not matching disperse count"
325+
)
326+
end
327+
end
328+
329+
def self.validate_storage_units_node_names(storage_units)
330+
storage_units.each do |storage_unit|
331+
msg = storage_unit.port > 0 ? "#{storage_unit.port}:" : ""
332+
msg += storage_unit.path
333+
raise InvalidPoolRequest.new("Node name is not specified for #{msg}") if storage_unit.node.name == ""
311334
end
312335
end
313336
end

mgr/src/server/plugins/pool_utils.cr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ def services_and_volfiles(req)
299299

300300
# Client Volfile
301301
tmpl = volfile_get("client")
302+
302303
client_volfile_content = Volgen.generate(tmpl, req.to_json, req.options)
303304

304305
# SHD Volfile
@@ -309,7 +310,7 @@ def services_and_volfiles(req)
309310
end
310311

311312
req.distribute_groups.each do |dist_grp|
312-
dist_grp.storage_units.each do |storage_unit|
313+
dist_grp.storage_units.each_with_index do |storage_unit, index|
313314
# Generate Service Unit
314315
service = StorageUnitService.new(req.name, storage_unit)
315316
services[storage_unit.node.name] = [] of MoanaTypes::ServiceUnit unless services[storage_unit.node.name]?
@@ -321,6 +322,13 @@ def services_and_volfiles(req)
321322
tmpl = volfile_get("storage_unit")
322323
storage_unit.volume.id = req.id
323324
storage_unit.volume.name = req.name
325+
326+
# Handle arbiter pools
327+
# Mark every 3rd storage-unit as type arbiter if distribute group has arbiter count > 0
328+
if dist_grp.arbiter_count > 0 && ((index + 1) % 3 == 0)
329+
storage_unit.type = "arbiter"
330+
end
331+
324332
content = Volgen.generate(tmpl, storage_unit.to_json)
325333
volfiles[storage_unit.node.name] = [] of MoanaTypes::Volfile unless volfiles[storage_unit.node.name]?
326334
volfiles[storage_unit.node.name] << MoanaTypes::Volfile.new(service.id, content)

tests/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ RUN git clone https://github.com/kadalu/glusterfs && \
2828

2929
RUN curl -fsSL https://crystal-lang.org/install.sh | sudo bash
3030

31-
cmd ["/usr/sbin/init"]
31+
cmd ["/usr/sbin/init"]

tests/all/pools.t

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ nodes.each do |node|
4545
TEST "mkdir -p /exports/pool19"
4646
TEST "mkdir -p /exports/pool20a"
4747
TEST "mkdir -p /exports/pool20b"
48+
TEST "mkdir -p /exports/pool21"
4849
end
4950

5051
USE_NODE nodes[0]
@@ -492,6 +493,35 @@ puts TEST "kadalu node list"
492493

493494
TEST "kadalu pool delete pool20a --mode=script"
494495

496+
# Test for Arbiter Pool type
497+
USE_NODE nodes[0]
498+
TEST "kadalu pool create pool21 arbiter server1:/exports/pool21/s1 server2:/exports/pool21/s2 server3:/exports/pool21/s3"
499+
500+
TEST "mkdir -p /mnt/pool21"
501+
502+
puts TEST "kadalu mount pool21 /mnt/pool21"
503+
puts TEST "df /mnt/pool21"
504+
505+
TEST "mkdir -p /mnt/pool21/d1"
506+
TEST "echo 'pool21' >> /mnt/pool21/d1/pool21.txt"
507+
508+
content = TEST "cat /exports/pool21/s1/d1/pool21.txt"
509+
EQUAL content.strip, "pool21", "Test if server1:/exports/pool21/s1/d1/pool21.txt has 'pool21'"
510+
511+
USE_NODE nodes[1]
512+
content = TEST "cat /exports/pool21/s2/d1/pool21.txt"
513+
EQUAL content.strip, "pool21", "Test if server2:/exports/pool21/s2/d1/pool21.txt has 'pool21'"
514+
515+
USE_NODE nodes[2]
516+
# Expect below to be a empty file
517+
content = TEST "cat /exports/pool21/s3/d1/pool21.txt"
518+
NOT_EQUAL content.strip, "pool21", "Test if server3:/exports/pool21/s3/d1/pool21.txt has 'pool21'"
519+
520+
USE_NODE nodes[0]
521+
522+
TEST "kadalu pool stop pool21 --mode=script"
523+
TEST "kadalu pool delete pool21 --mode=script"
524+
495525
nodes.each do |node|
496526
USE_NODE nodes[0]
497527
puts TEST "kadalu node remove #{node} --mode=script"

types/src/moana_types.cr

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ module MoanaTypes
109109
end
110110

111111
def type
112-
if @replica_count > 0
112+
if @replica_count >= 2 && @arbiter_count == 1
113+
"Arbiter"
114+
elsif @replica_count > 0
113115
@replica_keyword == "mirror" ? "Mirror" : "Replicate"
114116
elsif @disperse_count > 0
115117
"Disperse"

0 commit comments

Comments
 (0)