1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# GlusterFS module by James
# Copyright (C) 2010-2013+ James Shubin
# Written by James Shubin <james@shubin.ca>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# NOTE:
# sort the bricks in a logical manner... i think this is the optimal algorithm,
# but i'd be happy if someone thinks they can do better! this assumes that the
# bricks and hosts are named in a logical manner. alphanumeric sorting is used
# to determine the default ordering...
module Puppet::Parser::Functions
newfunction(:brick_layout_simple, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
Return the simple symmetrical brick list
Example:
$layout = brick_layout_simple($replica, $bricks)
notice("layout is: ${layout}")
This function is used internally for automatic brick layouts.
ENDHEREDOC
Puppet::Parser::Functions.function('brick_str_to_hash') # load function
# signature: replica, bricks -> bricks
unless args.length == 2
raise Puppet::ParseError, "brick_layout_simple(): wrong number of arguments (#{args.length}; must be 2)"
end
if not(args[0].is_a?(Integer)) and not(args[0].is_a?(String))
# NOTE: strings that convert to int's with .to_i are ok
raise Puppet::ParseError, "brick_layout_simple(): expects the first argument to be an integer, got #{args[0].inspect} which is of type #{args[0].class}"
end
unless args[1].is_a?(Array)
raise Puppet::ParseError, "brick_layout_simple(): expects the second argument to be an array, got #{args[1].inspect} which is of type #{args[1].class}"
end
replica = args[0].to_i # convert from string if needed
bricks = args[1]
collect = {}
parsed = function_brick_str_to_hash([bricks])
parsed.each do |x|
key = x['host']
val = x['path']
if not collect.has_key?(key)
collect[key] = [] # initialize
end
collect[key].push(val) # save in array
# TODO: ensure this array is always sorted (we could also do this after
# or always insert elements in the correct sorted order too :P)
collect[key] = collect[key].sort
end
# we also could do this sort here...
collect.keys.each do |x|
collect[x] = collect[x].sort
end
final = [] # final order...
# TODO: here we can probably detect if this is an asymmetrical configurations, or maybe bad naming...
while collect.size > 0
collect.keys.sort.each do |x|
# NOTE: this array should already be sorted!
p = collect[x].shift # assume an array of at least 1 element
final.push( { 'host' => x, 'path' => p } ) # save
if collect[x].size == 0 # maybe the array is empty now
collect.delete(x) # remove that empty list's key
end
end
end
# build final result
result = final.collect {|x| x['host']+':'+x['path'] }
result # return
end
end
# vim: ts=8
|