mogilefs-client 1.3.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/GNUmakefile +32 -0
- data/History.txt +23 -0
- data/LICENSE.txt +1 -0
- data/Manifest.txt +12 -1
- data/README.txt +22 -13
- data/bin/mog +37 -6
- data/lib/mogilefs.rb +19 -5
- data/lib/mogilefs/admin.rb +27 -34
- data/lib/mogilefs/backend.rb +106 -39
- data/lib/mogilefs/bigfile.rb +153 -0
- data/lib/mogilefs/client.rb +1 -5
- data/lib/mogilefs/httpfile.rb +65 -71
- data/lib/mogilefs/mogilefs.rb +102 -102
- data/lib/mogilefs/mysql.rb +166 -0
- data/lib/mogilefs/network.rb +64 -0
- data/lib/mogilefs/pool.rb +1 -1
- data/lib/mogilefs/util.rb +140 -9
- data/test/.gitignore +2 -0
- data/test/aggregate.rb +13 -0
- data/test/setup.rb +72 -91
- data/test/test_admin.rb +2 -2
- data/test/test_backend.rb +100 -38
- data/test/test_bigfile.rb +48 -0
- data/test/test_client.rb +7 -2
- data/test/test_db_backend.rb +73 -0
- data/test/test_mogilefs.rb +287 -107
- data/test/test_mysql.rb +94 -0
- data/test/test_network.rb +27 -0
- data/test/test_util.rb +59 -0
- metadata +22 -6
- data/lib/mogilefs/nfsfile.rb +0 -81
data/.gitignore
ADDED
data/GNUmakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# use GNU Make to run tests in parallel, and without depending on Rubygems
|
2
|
+
all:: test
|
3
|
+
|
4
|
+
T := $(wildcard test/test*.rb)
|
5
|
+
TO := $(subst .rb,.log,$(T))
|
6
|
+
|
7
|
+
test: $(T)
|
8
|
+
@cat $(TO) | ruby test/aggregate.rb
|
9
|
+
@$(RM) $(TO)
|
10
|
+
clean:
|
11
|
+
$(RM) $(TO) $(addsuffix +,$(TO))
|
12
|
+
|
13
|
+
t = $(basename $(notdir $@))
|
14
|
+
t_log = $(subst .rb,.log,$@)
|
15
|
+
|
16
|
+
$(T):
|
17
|
+
@echo $(t); ruby -I lib $@ $(TEST_OPTS) > $(t_log)+ 2>&1
|
18
|
+
@mv $(t_log)+ $(t_log)
|
19
|
+
|
20
|
+
# using make instead of rake since Rakefile takes too long to load
|
21
|
+
Manifest.txt:
|
22
|
+
git ls-files > $@+
|
23
|
+
mv $@+ $@
|
24
|
+
|
25
|
+
libs := $(wildcard lib/*.rb lib/*/*.rb)
|
26
|
+
flay_flags =
|
27
|
+
flog_flags =
|
28
|
+
flay: $(libs)
|
29
|
+
flay $(flay_flags) $^
|
30
|
+
flog: $(libs)
|
31
|
+
flog $(flog_flags) $^
|
32
|
+
.PHONY: $(T) Manifest.txt
|
data/History.txt
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
= 2.0.0
|
2
|
+
|
3
|
+
* use a set of standard exceptions based on MogileFS::Error,
|
4
|
+
this is an incompatible API change (hence the 2.0.0 version number).
|
5
|
+
* remove NFS support since it's gone in MogileFS 2.x and NFS is horrible
|
6
|
+
* mog timeouts and retries increased
|
7
|
+
* more consistent handling of bad sockets, all sockets used internally
|
8
|
+
are now explicitly non-blocking and IO.select is used for timeouts
|
9
|
+
instead of using threads behind our backs
|
10
|
+
* remove open-uri and net/http dependencies, they were bad with large files
|
11
|
+
* add paths_size() method, allowing single mogilefsd call to get size and paths
|
12
|
+
* add read-only MogileFS::Mysql driver, allowing mogilefsd to be bypassed
|
13
|
+
* use TCP_NODELAY when available on sockets that require low latency
|
14
|
+
* use TCP_CORK on bulk transfers to improve bandwidth usage
|
15
|
+
* better HTTP error handling
|
16
|
+
* verify_uris method in new MogileFS::Network module which allows
|
17
|
+
async verification of several URIs at once on the client side.
|
18
|
+
* handle multiple device failover correctly on HTTP uploads
|
19
|
+
* initial big_file read support (should be mogtool(1)-compatible)
|
20
|
+
* unit tests can be run in parallel using GNU Make, 3x faster on a Core2 Duo
|
21
|
+
* unit tests modified to use real sockets for easier verification of
|
22
|
+
timeout and error condition handling.
|
23
|
+
|
1
24
|
= 1.3.1
|
2
25
|
|
3
26
|
* Fix missing MogileFS::Util include for sysrwloop in MogileFS::MogileFS
|
data/LICENSE.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
.gitignore
|
2
|
+
GNUmakefile
|
1
3
|
History.txt
|
2
4
|
LICENSE.txt
|
3
5
|
Manifest.txt
|
@@ -7,15 +9,24 @@ bin/mog
|
|
7
9
|
lib/mogilefs.rb
|
8
10
|
lib/mogilefs/admin.rb
|
9
11
|
lib/mogilefs/backend.rb
|
12
|
+
lib/mogilefs/bigfile.rb
|
10
13
|
lib/mogilefs/client.rb
|
11
14
|
lib/mogilefs/httpfile.rb
|
12
15
|
lib/mogilefs/mogilefs.rb
|
13
|
-
lib/mogilefs/
|
16
|
+
lib/mogilefs/mysql.rb
|
17
|
+
lib/mogilefs/network.rb
|
14
18
|
lib/mogilefs/pool.rb
|
15
19
|
lib/mogilefs/util.rb
|
20
|
+
test/.gitignore
|
21
|
+
test/aggregate.rb
|
16
22
|
test/setup.rb
|
17
23
|
test/test_admin.rb
|
18
24
|
test/test_backend.rb
|
25
|
+
test/test_bigfile.rb
|
19
26
|
test/test_client.rb
|
27
|
+
test/test_db_backend.rb
|
20
28
|
test/test_mogilefs.rb
|
29
|
+
test/test_mysql.rb
|
30
|
+
test/test_network.rb
|
21
31
|
test/test_pool.rb
|
32
|
+
test/test_util.rb
|
data/README.txt
CHANGED
@@ -14,10 +14,20 @@ File bugs:
|
|
14
14
|
|
15
15
|
http://rubyforge.org/tracker/?func=add&group_id=1513&atid=5921
|
16
16
|
|
17
|
+
Source repository (git):
|
18
|
+
|
19
|
+
git://git.bogomips.org/mogilefs-client.git
|
20
|
+
|
21
|
+
http://git.bogomips.org/mogilefs-client.git
|
22
|
+
|
23
|
+
Repository browser (cgit):
|
24
|
+
|
25
|
+
http://git.bogomips.org/cgit/mogilefs-client.git
|
26
|
+
|
17
27
|
== About
|
18
28
|
|
19
29
|
A Ruby MogileFS client. MogileFS is a distributed filesystem written
|
20
|
-
by Danga Interactive. This client supports
|
30
|
+
by Danga Interactive. This client only supports HTTP.
|
21
31
|
|
22
32
|
For information on MogileFS see:
|
23
33
|
|
@@ -25,7 +35,8 @@ http://danga.com/mogilefs/
|
|
25
35
|
|
26
36
|
== Installing mogilefs-client
|
27
37
|
|
28
|
-
First you need a MogileFS setup. You can find information on how to do
|
38
|
+
First you need a MogileFS setup. You can find information on how to do
|
39
|
+
that at the above URL.
|
29
40
|
|
30
41
|
Then install the gem:
|
31
42
|
|
@@ -35,32 +46,30 @@ Then install the gem:
|
|
35
46
|
|
36
47
|
# Create a new instance that will communicate with these trackers:
|
37
48
|
hosts = %w[192.168.1.69:6001 192.168.1.70:6001]
|
38
|
-
mg = MogileFS::MogileFS.new(:domain => 'test', :hosts => hosts
|
39
|
-
|
40
|
-
|
49
|
+
mg = MogileFS::MogileFS.new(:domain => 'test', :hosts => hosts)
|
50
|
+
|
41
51
|
# Stores "A bunch of text to store" into 'some_key' with a class of 'text'.
|
42
52
|
mg.store_content 'some_key', 'text', "A bunch of text to store"
|
43
|
-
|
53
|
+
|
44
54
|
# Retrieve data from 'some_key'
|
45
55
|
data = mg.get_file_data 'some_key'
|
46
|
-
|
56
|
+
|
47
57
|
# Store the contents of 'image.jpeg' into the key 'my_image' with a class of
|
48
58
|
# 'image'.
|
49
59
|
mg.store_file 'my_image', 'image', 'image.jpeg'
|
50
|
-
|
60
|
+
|
51
61
|
# Store the contents of 'image.jpeg' into the key 'my_image' with a class of
|
52
62
|
# 'image' using an open IO.
|
53
63
|
File.open 'image.jpeg' do |fp|
|
54
64
|
mg.store_file 'my_image', 'image', fp
|
55
65
|
end
|
56
|
-
|
66
|
+
|
57
67
|
# Remove the key 'my_image' and 'some_key'.
|
58
68
|
mg.delete 'my_image'
|
59
69
|
mg.delete 'some_key'
|
60
70
|
|
61
71
|
== WARNING!
|
62
72
|
|
63
|
-
This client is only
|
64
|
-
|
65
|
-
|
66
|
-
|
73
|
+
This client is only supported in HTTP mode. NFS mode was previously
|
74
|
+
supported in 1.3.x, but since MogileFS 2.x has dropped support for
|
75
|
+
NFS, this client has removed support for it.
|
data/bin/mog
CHANGED
@@ -14,6 +14,8 @@ def parse_config_file!(path, overwrite = false)
|
|
14
14
|
dest[$1.to_sym] = $2
|
15
15
|
elsif m = /^(?:trackers|hosts)\s*=\s*(.*)/.match(line)
|
16
16
|
dest[:hosts] = $1.split(/\s*,\s*/)
|
17
|
+
elsif m = /^timeout\s*=\s*(.*)/.match(line)
|
18
|
+
dest[:timeout] = m[1].to_f
|
17
19
|
else
|
18
20
|
STDERR.puts "Ignored configuration line: #{line}" unless /^#/.match(line)
|
19
21
|
end
|
@@ -31,6 +33,7 @@ config_file = nil
|
|
31
33
|
ls_l = false
|
32
34
|
ls_h = false
|
33
35
|
test = {}
|
36
|
+
cat = { :raw => false }
|
34
37
|
|
35
38
|
ARGV.options do |x|
|
36
39
|
x.banner = "Usage: #{$0} [options] <command> [<arguments>]"
|
@@ -45,6 +48,7 @@ ARGV.options do |x|
|
|
45
48
|
end
|
46
49
|
|
47
50
|
x.on('-e', 'True if key exists') { test[:e] = true }
|
51
|
+
x.on('-r', '--raw', 'show raw big_info file information') { cat[:raw] = true }
|
48
52
|
|
49
53
|
x.on('-C', '--class=s', 'class') { |klass| cli_cfg[:class] = klass }
|
50
54
|
x.on('-d', '--domain=s', 'domain') { |domain| cli_cfg[:domain] = domain }
|
@@ -67,7 +71,7 @@ env_cfg = {}
|
|
67
71
|
if ENV["MOG_TRACKERS"]
|
68
72
|
env_cfg[:hosts] = ENV["MOG_TRACKERS"].split(/\s*,\s*/)
|
69
73
|
end
|
70
|
-
if ENV["MOG_HOSTS"] && env_cfg[:hosts].empty?
|
74
|
+
if ENV["MOG_HOSTS"] && (env_cfg[:hosts] || []).empty?
|
71
75
|
env_cfg[:hosts] = ENV["MOG_HOSTS"].split(/\s*,\s*/)
|
72
76
|
end
|
73
77
|
env_cfg[:domain] = ENV["MOG_DOMAIN"] if ENV["MOG_DOMAIN"]
|
@@ -91,20 +95,42 @@ unless cmd = ARGV.shift
|
|
91
95
|
exit 1
|
92
96
|
end
|
93
97
|
|
98
|
+
cfg[:timeout] ||= 30 # longer timeout for interactive use
|
94
99
|
include MogileFS::Util
|
95
100
|
mg = MogileFS::MogileFS.new(cfg)
|
96
101
|
|
102
|
+
def store_file_retry(mg, key, storage_class, filepath)
|
103
|
+
tries = 0
|
104
|
+
begin
|
105
|
+
mg.store_file(key, storage_class, filepath)
|
106
|
+
rescue MogileFS::UnreadableSocketError,
|
107
|
+
MogileFS::Backend::NoDevicesError => err
|
108
|
+
if ((tries += 1) < 10)
|
109
|
+
STDERR.puts "Retrying on error: #{err}: #{err.message} tries: #{tries}"
|
110
|
+
retry
|
111
|
+
else
|
112
|
+
STDERR.puts "FATAL: #{err}: #{err.message} tries: #{tries}"
|
113
|
+
end
|
114
|
+
exit 1
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
97
118
|
begin
|
98
119
|
case cmd
|
99
120
|
when 'cp'
|
100
121
|
filename = ARGV.shift or raise ArgumentError, '<filename> <key>'
|
101
122
|
key = ARGV.shift or raise ArgumentError, '<filename> <key>'
|
102
123
|
ARGV.shift and raise ArgumentError, '<filename> <key>'
|
103
|
-
cfg[:class]
|
104
|
-
mg.store_file(key, cfg[:class], filename)
|
124
|
+
store_file_retry(mg, key, cfg[:class], filename)
|
105
125
|
when 'cat'
|
106
126
|
ARGV.empty? and raise ArgumentError, '<key1> [<key2> ...]'
|
107
|
-
ARGV.each
|
127
|
+
ARGV.each do |key|
|
128
|
+
if (!cat[:raw] && key =~ /^_big_info:/)
|
129
|
+
mg.bigfile_write(key, STDOUT, {:verify => true})
|
130
|
+
else
|
131
|
+
mg.get_file_data(key) { |fp| sysrwloop(fp, STDOUT) }
|
132
|
+
end
|
133
|
+
end
|
108
134
|
when 'ls'
|
109
135
|
prefixes = ARGV.empty? ? [ nil ] : ARGV
|
110
136
|
prefixes.each do |prefix|
|
@@ -160,9 +186,14 @@ begin
|
|
160
186
|
buf = ''
|
161
187
|
tmp = Tempfile.new('mog-tee') # TODO: explore Transfer-Encoding:chunked :)
|
162
188
|
at_exit { tmp.unlink }
|
189
|
+
|
190
|
+
# if stdout is pointing to /dev/null, don't bother installing the filter.
|
191
|
+
STDOUT.sync = true
|
192
|
+
tee_filter = File.stat('/dev/null') == STDOUT.stat ?
|
193
|
+
nil : Proc.new { |buf| STDOUT.write(buf); buf }
|
163
194
|
begin
|
164
|
-
sysrwloop(STDIN, tmp)
|
165
|
-
mg
|
195
|
+
sysrwloop(STDIN, tmp, tee_filter)
|
196
|
+
store_file_retry(mg, key, cfg[:class], tmp.path)
|
166
197
|
ensure
|
167
198
|
tmp.close
|
168
199
|
end
|
data/lib/mogilefs.rb
CHANGED
@@ -6,21 +6,35 @@
|
|
6
6
|
|
7
7
|
module MogileFS
|
8
8
|
|
9
|
-
VERSION = '
|
9
|
+
VERSION = '2.0.0'.freeze
|
10
10
|
|
11
11
|
##
|
12
12
|
# Raised when a socket remains unreadable for too long.
|
13
13
|
|
14
|
-
class
|
14
|
+
class Error < StandardError; end
|
15
|
+
class UnreadableSocketError < Error; end
|
16
|
+
class SizeMismatchError < Error; end
|
17
|
+
class ChecksumMismatchError < RuntimeError; end
|
18
|
+
class ReadOnlyError < Error
|
19
|
+
def message; 'readonly mogilefs'; end
|
20
|
+
end
|
21
|
+
class EmptyPathError < Error
|
22
|
+
def message; 'Empty path for mogile upload'; end
|
23
|
+
end
|
24
|
+
|
25
|
+
class UnsupportedPathError < Error; end
|
26
|
+
class RequestTruncatedError < Error; end
|
27
|
+
class InvalidResponseError < Error; end
|
28
|
+
class UnreachableBackendError < Error
|
29
|
+
def message; "couldn't connect to mogilefsd backend"; end
|
30
|
+
end
|
15
31
|
|
16
32
|
end
|
17
33
|
|
18
|
-
require 'socket'
|
19
|
-
|
20
34
|
require 'mogilefs/backend'
|
21
|
-
require 'mogilefs/nfsfile'
|
22
35
|
require 'mogilefs/httpfile'
|
23
36
|
require 'mogilefs/client'
|
37
|
+
require 'mogilefs/bigfile'
|
24
38
|
require 'mogilefs/mogilefs'
|
25
39
|
require 'mogilefs/admin'
|
26
40
|
|
data/lib/mogilefs/admin.rb
CHANGED
@@ -40,9 +40,8 @@ class MogileFS::Admin < MogileFS::Client
|
|
40
40
|
# "altmask"=>""}]
|
41
41
|
|
42
42
|
def get_hosts(hostid = nil)
|
43
|
-
|
44
|
-
|
45
|
-
return clean('hosts', 'host', res)
|
43
|
+
clean('hosts', 'host',
|
44
|
+
@backend.get_hosts(hostid ? { :hostid => hostid } : {}))
|
46
45
|
end
|
47
46
|
|
48
47
|
##
|
@@ -62,9 +61,8 @@ class MogileFS::Admin < MogileFS::Client
|
|
62
61
|
# "mb_total"=>""}]
|
63
62
|
|
64
63
|
def get_devices(devid = nil)
|
65
|
-
|
66
|
-
|
67
|
-
return clean('devices', 'dev', res)
|
64
|
+
clean('devices', 'dev',
|
65
|
+
@backend.get_devices(devid ? { :devid => devid } : {}))
|
68
66
|
end
|
69
67
|
|
70
68
|
##
|
@@ -88,8 +86,8 @@ class MogileFS::Admin < MogileFS::Client
|
|
88
86
|
# "key"=>"new_new_key"}]
|
89
87
|
|
90
88
|
def list_fids(from_fid, to_fid)
|
91
|
-
|
92
|
-
|
89
|
+
clean('fid_count', 'fid_',
|
90
|
+
@backend.list_fids(:from => from_fid, :to => to_fid))
|
93
91
|
end
|
94
92
|
|
95
93
|
##
|
@@ -126,7 +124,7 @@ class MogileFS::Admin < MogileFS::Client
|
|
126
124
|
stats.delete 'file' if stats['file'].empty?
|
127
125
|
stats.delete 'replication' if stats['replication'].empty?
|
128
126
|
|
129
|
-
|
127
|
+
stats
|
130
128
|
end
|
131
129
|
|
132
130
|
##
|
@@ -148,25 +146,24 @@ class MogileFS::Admin < MogileFS::Client
|
|
148
146
|
domains[res["domain#{i}"]] = Hash[*domain.flatten]
|
149
147
|
end
|
150
148
|
|
151
|
-
|
149
|
+
domains
|
152
150
|
end
|
153
151
|
|
154
152
|
##
|
155
153
|
# Creates a new domain named +domain+. Returns nil if creation failed.
|
156
154
|
|
157
155
|
def create_domain(domain)
|
158
|
-
raise
|
156
|
+
raise MogileFS::ReadOnlyError if readonly?
|
159
157
|
res = @backend.create_domain :domain => domain
|
160
|
-
|
158
|
+
res ? res['domain'] : nil
|
161
159
|
end
|
162
160
|
|
163
161
|
##
|
164
162
|
# Deletes +domain+. Returns true if successful, false if not.
|
165
163
|
|
166
164
|
def delete_domain(domain)
|
167
|
-
raise
|
168
|
-
|
169
|
-
return !res.nil?
|
165
|
+
raise MogileFS::ReadOnlyError if readonly?
|
166
|
+
! @backend.delete_domain(:domain => domain).nil?
|
170
167
|
end
|
171
168
|
|
172
169
|
##
|
@@ -174,7 +171,7 @@ class MogileFS::Admin < MogileFS::Client
|
|
174
171
|
# +mindevcount+ devices. Returns nil on failure.
|
175
172
|
|
176
173
|
def create_class(domain, klass, mindevcount)
|
177
|
-
|
174
|
+
modify_class(domain, klass, mindevcount, :create)
|
178
175
|
end
|
179
176
|
|
180
177
|
##
|
@@ -182,7 +179,7 @@ class MogileFS::Admin < MogileFS::Client
|
|
182
179
|
# devices. Returns nil on failure.
|
183
180
|
|
184
181
|
def update_class(domain, klass, mindevcount)
|
185
|
-
|
182
|
+
modify_class(domain, klass, mindevcount, :update)
|
186
183
|
end
|
187
184
|
|
188
185
|
##
|
@@ -190,8 +187,7 @@ class MogileFS::Admin < MogileFS::Client
|
|
190
187
|
# not.
|
191
188
|
|
192
189
|
def delete_class(domain, klass)
|
193
|
-
|
194
|
-
return !res.nil?
|
190
|
+
! @backend.delete_class(:domain => domain, :class => klass).nil?
|
195
191
|
end
|
196
192
|
|
197
193
|
##
|
@@ -202,23 +198,22 @@ class MogileFS::Admin < MogileFS::Client
|
|
202
198
|
raise ArgumentError, "Must specify ip and port" unless \
|
203
199
|
args.include? :ip and args.include? :port
|
204
200
|
|
205
|
-
|
201
|
+
modify_host(host, args, 'create')
|
206
202
|
end
|
207
203
|
|
208
204
|
##
|
209
205
|
# Updates +host+ with +args+. Returns true if successful, false if not.
|
210
206
|
|
211
207
|
def update_host(host, args = {})
|
212
|
-
|
208
|
+
modify_host(host, args, 'update')
|
213
209
|
end
|
214
210
|
|
215
211
|
##
|
216
212
|
# Deletes host +host+. Returns nil on failure.
|
217
213
|
|
218
214
|
def delete_host(host)
|
219
|
-
raise
|
220
|
-
|
221
|
-
return !res.nil?
|
215
|
+
raise MogileFS::ReadOnlyError if readonly?
|
216
|
+
! @backend.delete_host(:host => host).nil?
|
222
217
|
end
|
223
218
|
|
224
219
|
##
|
@@ -226,9 +221,8 @@ class MogileFS::Admin < MogileFS::Client
|
|
226
221
|
# 'alive', 'down', or 'dead'.
|
227
222
|
|
228
223
|
def change_device_state(host, device, state)
|
229
|
-
raise
|
230
|
-
|
231
|
-
return !res.nil?
|
224
|
+
raise MogileFS::ReadOnlyError if readonly?
|
225
|
+
! @backend.set_state(:host => host, :device => device, :state => state).nil?
|
232
226
|
end
|
233
227
|
|
234
228
|
protected unless defined? $TESTING
|
@@ -238,11 +232,11 @@ class MogileFS::Admin < MogileFS::Client
|
|
238
232
|
# +action+. Returns the class name if successful, nil if not.
|
239
233
|
|
240
234
|
def modify_class(domain, klass, mindevcount, action)
|
241
|
-
raise
|
235
|
+
raise MogileFS::ReadOnlyError if readonly?
|
242
236
|
res = @backend.send("#{action}_class", :domain => domain, :class => klass,
|
243
237
|
:mindevcount => mindevcount)
|
244
238
|
|
245
|
-
|
239
|
+
res ? res['class'] : nil
|
246
240
|
end
|
247
241
|
|
248
242
|
##
|
@@ -251,8 +245,7 @@ class MogileFS::Admin < MogileFS::Client
|
|
251
245
|
|
252
246
|
def modify_host(host, args = {}, action = 'create')
|
253
247
|
args[:host] = host
|
254
|
-
|
255
|
-
return !res.nil?
|
248
|
+
! @backend.send("#{action}_host", args).nil?
|
256
249
|
end
|
257
250
|
|
258
251
|
##
|
@@ -271,9 +264,9 @@ class MogileFS::Admin < MogileFS::Client
|
|
271
264
|
# "host1_status"=>"alive",
|
272
265
|
# "host1_altmask"=>""}
|
273
266
|
# admin.clean 'hosts', 'host', res
|
274
|
-
#
|
267
|
+
#
|
275
268
|
# Returns:
|
276
|
-
#
|
269
|
+
#
|
277
270
|
# [{"status"=>"alive",
|
278
271
|
# "http_get_port"=>"",
|
279
272
|
# "http_port"=>"",
|
@@ -286,7 +279,7 @@ class MogileFS::Admin < MogileFS::Client
|
|
286
279
|
|
287
280
|
def clean(count, prefix, res, underscore = true)
|
288
281
|
underscore = underscore ? '_' : ''
|
289
|
-
|
282
|
+
(1..res[count].to_i).map do |i|
|
290
283
|
dev = res.select { |k,_| k =~ /^#{prefix}#{i}#{underscore}/ }.map do |k,v|
|
291
284
|
[k.sub(/^#{prefix}#{i}#{underscore}/, ''), v]
|
292
285
|
end
|