mogilefs-client 2.2.0 → 3.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +11 -0
- data/.gemtest +0 -0
- data/.gitignore +4 -0
- data/.wrongdoc.yml +5 -0
- data/GIT-VERSION-GEN +28 -0
- data/GNUmakefile +44 -0
- data/HACKING +33 -0
- data/{History.txt → History} +0 -1
- data/{LICENSE.txt → LICENSE} +0 -1
- data/Manifest.txt +34 -7
- data/README +51 -0
- data/Rakefile +11 -11
- data/TODO +10 -0
- data/bin/mog +109 -68
- data/examples/mogstored_rack.rb +189 -0
- data/lib/mogilefs.rb +56 -17
- data/lib/mogilefs/admin.rb +128 -62
- data/lib/mogilefs/backend.rb +205 -95
- data/lib/mogilefs/bigfile.rb +54 -70
- data/lib/mogilefs/bigfile/filter.rb +58 -0
- data/lib/mogilefs/chunker.rb +30 -0
- data/lib/mogilefs/client.rb +0 -2
- data/lib/mogilefs/copy_stream.rb +30 -0
- data/lib/mogilefs/http_file.rb +175 -0
- data/lib/mogilefs/http_reader.rb +79 -0
- data/lib/mogilefs/mogilefs.rb +242 -148
- data/lib/mogilefs/mysql.rb +3 -4
- data/lib/mogilefs/paths_size.rb +24 -0
- data/lib/mogilefs/pool.rb +0 -1
- data/lib/mogilefs/socket.rb +9 -0
- data/lib/mogilefs/socket/kgio.rb +55 -0
- data/lib/mogilefs/socket/pure_ruby.rb +70 -0
- data/lib/mogilefs/socket_common.rb +58 -0
- data/lib/mogilefs/util.rb +6 -169
- data/test/aggregate.rb +11 -11
- data/test/exec.rb +72 -0
- data/test/fresh.rb +222 -0
- data/test/integration.rb +43 -0
- data/test/setup.rb +1 -0
- data/test/socket_test.rb +98 -0
- data/test/test_admin.rb +14 -37
- data/test/test_backend.rb +50 -107
- data/test/test_bigfile.rb +2 -2
- data/test/test_db_backend.rb +1 -2
- data/test/test_fresh.rb +8 -0
- data/test/test_http_reader.rb +34 -0
- data/test/test_mogilefs.rb +278 -98
- data/test/test_mogilefs_integration.rb +174 -0
- data/test/test_mogilefs_integration_large_pipe.rb +62 -0
- data/test/test_mogilefs_integration_list_keys.rb +40 -0
- data/test/test_mogilefs_socket_kgio.rb +11 -0
- data/test/test_mogilefs_socket_pure.rb +7 -0
- data/test/test_mogstored_rack.rb +89 -0
- data/test/test_mogtool_bigfile.rb +116 -0
- data/test/test_mysql.rb +1 -2
- data/test/test_pool.rb +1 -1
- data/test/test_unit_mogstored_rack.rb +72 -0
- metadata +76 -54
- data/README.txt +0 -80
- data/lib/mogilefs/httpfile.rb +0 -157
- data/lib/mogilefs/network.rb +0 -107
- data/test/test_network.rb +0 -56
- data/test/test_util.rb +0 -121
data/.document
ADDED
data/.gemtest
ADDED
File without changes
|
data/.gitignore
CHANGED
data/.wrongdoc.yml
ADDED
data/GIT-VERSION-GEN
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
CONSTANT = "MogileFS::VERSION"
|
3
|
+
RVF = "lib/mogilefs/version.rb"
|
4
|
+
DEF_VER = "v3.0.0-rc1"
|
5
|
+
vn = DEF_VER
|
6
|
+
|
7
|
+
# First see if there is a version file (included in release tarballs),
|
8
|
+
# then try git-describe, then default.
|
9
|
+
if File.exist?(".git")
|
10
|
+
describe = `git describe --abbrev=4 HEAD 2>/dev/null`.strip
|
11
|
+
case describe
|
12
|
+
when /\Av[0-9]*/
|
13
|
+
vn = describe
|
14
|
+
system(*%w(git update-index -q --refresh))
|
15
|
+
unless `git diff-index --name-only HEAD --`.chomp.empty?
|
16
|
+
vn << "-dirty"
|
17
|
+
end
|
18
|
+
vn.tr!('-', '.')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
vn = vn.sub!(/\Av/, "")
|
23
|
+
new_ruby_version = "#{CONSTANT} = '#{vn}'\n"
|
24
|
+
cur_ruby_version = File.read(RVF) rescue nil
|
25
|
+
if new_ruby_version != cur_ruby_version
|
26
|
+
File.open(RVF, "w") { |fp| fp.write(new_ruby_version) }
|
27
|
+
end
|
28
|
+
puts vn if $0 == __FILE__
|
data/GNUmakefile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# use GNU Make to run tests in parallel, and without depending on Rubygems
|
2
2
|
all:: test
|
3
|
+
RSYNC_DEST := bogomips.org:/srv/bogomips/mogilefs-client
|
4
|
+
git_version_gen := $(shell ./GIT-VERSION-GEN)
|
3
5
|
|
4
6
|
T := $(wildcard test/test*.rb)
|
5
7
|
TO := $(subst .rb,.log,$(T))
|
@@ -31,10 +33,12 @@ $(T): export RUBYLIB := $(CURDIR)/lib:$(RUBYLIB)
|
|
31
33
|
$(T):
|
32
34
|
$(run_test)
|
33
35
|
|
36
|
+
RUBY_VERSION_FILE = lib/mogilefs/version.rb
|
34
37
|
# using make instead of rake since Rakefile takes too long to load
|
35
38
|
manifest: Manifest.txt
|
36
39
|
Manifest.txt:
|
37
40
|
git ls-files > $@+
|
41
|
+
echo $(RUBY_VERSION_FILE) >> $@+
|
38
42
|
cmp $@+ $@ || mv $@+ $@
|
39
43
|
$(RM) -f $@+
|
40
44
|
|
@@ -52,3 +56,43 @@ flay: $(libs)
|
|
52
56
|
flog: $(libs)
|
53
57
|
flog $(flog_flags) $^
|
54
58
|
.PHONY: $(T) Manifest.txt
|
59
|
+
|
60
|
+
check-warnings:
|
61
|
+
@(for i in $$(git ls-files '*.rb'| grep -v '^setup\.rb$$'); \
|
62
|
+
do ruby -d -W2 -c $$i; done) | grep -v '^Syntax OK$$' || :
|
63
|
+
RSYNC = rsync
|
64
|
+
WRONGDOC = wrongdoc
|
65
|
+
|
66
|
+
doc:: .document .wrongdoc.yml $(pkg_extra)
|
67
|
+
-find lib -type f -name '*.rbc' -exec rm -f '{}' ';'
|
68
|
+
$(RM) -r doc
|
69
|
+
$(WRONGDOC) all
|
70
|
+
install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
|
71
|
+
cd doc && \
|
72
|
+
ln -s README README.txt && \
|
73
|
+
ln -s README.html README_txt.html && \
|
74
|
+
ln -s LICENSE LICENSE.txt && \
|
75
|
+
ln -s LICENSE.html LICENSE_txt.html && \
|
76
|
+
ln -s History History.txt && \
|
77
|
+
ln -s History.html History_txt.html
|
78
|
+
|
79
|
+
# Create gzip variants of the same timestamp as the original so nginx
|
80
|
+
# "gzip_static on" can serve the gzipped versions directly.
|
81
|
+
doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
|
82
|
+
doc_gz:
|
83
|
+
for i in $(docs); do \
|
84
|
+
gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
|
85
|
+
|
86
|
+
# this requires GNU coreutils variants
|
87
|
+
ifneq ($(RSYNC_DEST),)
|
88
|
+
publish_doc:
|
89
|
+
-git set-file-times
|
90
|
+
$(MAKE) doc
|
91
|
+
find doc/images -type f | \
|
92
|
+
TZ=UTC xargs touch -d '1970-01-01 00:00:06' doc/rdoc.css
|
93
|
+
$(MAKE) doc_gz
|
94
|
+
$(RSYNC) -av doc/ $(RSYNC_DEST)/
|
95
|
+
git ls-files | xargs touch
|
96
|
+
endif
|
97
|
+
|
98
|
+
.PHONY: doc .FORCE-GIT-VERSION-FILE
|
data/HACKING
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
= Hacking mogilefs-client for Ruby
|
2
|
+
|
3
|
+
* The latest code is available via git:
|
4
|
+
- git://bogomips.org/mogilefs-client.git
|
5
|
+
- git://repo.or.cz/ruby-mogilefs-client
|
6
|
+
|
7
|
+
* Follow conventions set in existing code, don't add hard runtime
|
8
|
+
dependencies outside of the standard Ruby library.
|
9
|
+
|
10
|
+
* Do not hesitate to send plain-text(-only) email to Eric Wong at
|
11
|
+
mailto:normalperson@yhbt.net about anything not covered in
|
12
|
+
the documentation or mailing list archives. General MogileFS
|
13
|
+
topics can go to the public mailing list at mailto:mogile@googlegroups.com
|
14
|
+
You may still email Wong directly if you do not trust the corporation
|
15
|
+
that hosts the public mailing list.
|
16
|
+
|
17
|
+
* Use "git format-patch" and "git send-email" for sending patches.
|
18
|
+
|
19
|
+
* Use "git request-pull" as a guideline for formatting pull-requests.
|
20
|
+
|
21
|
+
* Test with the latest upstream MogileFS and Ruby versions.
|
22
|
+
|
23
|
+
* Integration tests exist for setting up a fresh MogileFS instance
|
24
|
+
with a single host and device using a SQLite backend if you
|
25
|
+
have "mogdbsetup", "mogilefsd", and "mogstored" in your PATH.
|
26
|
+
|
27
|
+
* Setting MOG_TEST_TRACKERS= to a comma-delimited list of trackers
|
28
|
+
can enable additional integration tests against a live tracker
|
29
|
+
(with multiple devices/hosts).
|
30
|
+
|
31
|
+
* Tests may be run in parallel using GNU make:
|
32
|
+
|
33
|
+
make -j6 test
|
data/{History.txt → History}
RENAMED
data/{LICENSE.txt → LICENSE}
RENAMED
data/Manifest.txt
CHANGED
@@ -1,33 +1,60 @@
|
|
1
|
+
.document
|
1
2
|
.gitignore
|
3
|
+
.wrongdoc.yml
|
4
|
+
GIT-VERSION-GEN
|
2
5
|
GNUmakefile
|
3
|
-
|
4
|
-
|
6
|
+
HACKING
|
7
|
+
History
|
8
|
+
LICENSE
|
5
9
|
Manifest.txt
|
6
|
-
README
|
10
|
+
README
|
7
11
|
Rakefile
|
12
|
+
TODO
|
8
13
|
bin/mog
|
14
|
+
examples/mogstored_rack.rb
|
9
15
|
lib/mogilefs.rb
|
10
16
|
lib/mogilefs/admin.rb
|
11
17
|
lib/mogilefs/backend.rb
|
12
18
|
lib/mogilefs/bigfile.rb
|
19
|
+
lib/mogilefs/bigfile/filter.rb
|
20
|
+
lib/mogilefs/chunker.rb
|
13
21
|
lib/mogilefs/client.rb
|
14
|
-
lib/mogilefs/
|
22
|
+
lib/mogilefs/copy_stream.rb
|
23
|
+
lib/mogilefs/http_file.rb
|
24
|
+
lib/mogilefs/http_reader.rb
|
15
25
|
lib/mogilefs/mogilefs.rb
|
16
26
|
lib/mogilefs/mysql.rb
|
17
|
-
lib/mogilefs/
|
27
|
+
lib/mogilefs/paths_size.rb
|
18
28
|
lib/mogilefs/pool.rb
|
29
|
+
lib/mogilefs/socket.rb
|
30
|
+
lib/mogilefs/socket/kgio.rb
|
31
|
+
lib/mogilefs/socket/pure_ruby.rb
|
32
|
+
lib/mogilefs/socket_common.rb
|
19
33
|
lib/mogilefs/util.rb
|
20
34
|
setup.rb
|
21
35
|
test/.gitignore
|
22
36
|
test/aggregate.rb
|
37
|
+
test/exec.rb
|
38
|
+
test/fresh.rb
|
39
|
+
test/integration.rb
|
23
40
|
test/setup.rb
|
41
|
+
test/socket_test.rb
|
24
42
|
test/test_admin.rb
|
25
43
|
test/test_backend.rb
|
26
44
|
test/test_bigfile.rb
|
27
45
|
test/test_client.rb
|
28
46
|
test/test_db_backend.rb
|
47
|
+
test/test_fresh.rb
|
48
|
+
test/test_http_reader.rb
|
29
49
|
test/test_mogilefs.rb
|
50
|
+
test/test_mogilefs_integration.rb
|
51
|
+
test/test_mogilefs_integration_large_pipe.rb
|
52
|
+
test/test_mogilefs_integration_list_keys.rb
|
53
|
+
test/test_mogilefs_socket_kgio.rb
|
54
|
+
test/test_mogilefs_socket_pure.rb
|
55
|
+
test/test_mogstored_rack.rb
|
56
|
+
test/test_mogtool_bigfile.rb
|
30
57
|
test/test_mysql.rb
|
31
|
-
test/test_network.rb
|
32
58
|
test/test_pool.rb
|
33
|
-
test/
|
59
|
+
test/test_unit_mogstored_rack.rb
|
60
|
+
lib/mogilefs/version.rb
|
data/README
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
= mogilefs-client - MogileFS client library for Ruby
|
2
|
+
|
3
|
+
A MogileFS client library for Ruby. MogileFS is an open source
|
4
|
+
distributed filesystem, see: http://mogilefs.org for more details. This
|
5
|
+
library allows any Ruby application to read, write and delete files in a
|
6
|
+
MogileFS instance.
|
7
|
+
|
8
|
+
== Links
|
9
|
+
|
10
|
+
rdoc :: http://bogomips.org/mogilefs-client
|
11
|
+
mogilefs :: http://mogilefs.org/
|
12
|
+
list :: mailto:mogile@googlegroups.com
|
13
|
+
email :: mailto:normalperson@yhbt.net
|
14
|
+
repo :: git://bogomips.org/mogilefs-client.git
|
15
|
+
cgit :: http://bogomips.org/mogilefs-client.git
|
16
|
+
gitweb :: http://repo.or.cz/w/ruby-mogilefs-client.git
|
17
|
+
|
18
|
+
== Install
|
19
|
+
|
20
|
+
First you need a MogileFS 2.x installation. You can find information on
|
21
|
+
how to do that at http://mogilefs.org
|
22
|
+
|
23
|
+
Then install the RubyGem:
|
24
|
+
|
25
|
+
$ gem install mogilefs-client
|
26
|
+
|
27
|
+
This library supports Ruby 1.8.7 and later, but Ruby 1.9.3 is
|
28
|
+
recommended. No other libraries are required on the client.
|
29
|
+
|
30
|
+
== Usage
|
31
|
+
|
32
|
+
See MogileFS::MogileFS
|
33
|
+
|
34
|
+
== Contact
|
35
|
+
|
36
|
+
Feedback (bug reports, user/development dicussion, patches, pull
|
37
|
+
requests) are greatly appreciated and handled via email. We currently
|
38
|
+
piggy-back onto the public MogileFS
|
39
|
+
{mailing list}[mailto:mogile@googlegroups.com] for feedback.
|
40
|
+
|
41
|
+
If you do not want to deal with the corporate host of the MogileFS
|
42
|
+
mailing list, or if you wish to keep your issue secret, feel free to
|
43
|
+
email {Eric Wong at}[mailto:normalperson@yhbt.net].
|
44
|
+
|
45
|
+
Do not expect Eric Wong to read HTML mail under any circumstances.
|
46
|
+
|
47
|
+
== WARNING!
|
48
|
+
|
49
|
+
This client is only supported in HTTP mode. NFS mode was previously
|
50
|
+
supported in 1.3.x, but since MogileFS 2.x has dropped support for
|
51
|
+
NFS, this client has removed support for it.
|
data/Rakefile
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'hoe'
|
3
|
+
load "./GIT-VERSION-GEN"
|
3
4
|
|
4
5
|
$:.unshift 'lib'
|
5
6
|
require 'mogilefs'
|
7
|
+
Hoe.plugin :seattlerb
|
6
8
|
|
7
|
-
Hoe.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
p.extra_dev_deps << ['ZenTest', '>= 3.6.1']
|
9
|
+
Hoe.spec 'mogilefs-client' do
|
10
|
+
self.rubyforge_name = 'seattlerb'
|
11
|
+
developer 'Eric Wong', 'normalperson@yhbt.net'
|
12
|
+
# developer 'drbrain@segment7.net', 'Eric Hodel'
|
13
|
+
self.readme_file = "README"
|
14
|
+
self.history_file = "History"
|
15
|
+
self.url = "http://bogomips.org/mogilefs-client"
|
16
|
+
self.description = self.paragraphs_of("README", 1)
|
17
|
+
self.summary = "MogileFS client library for Ruby"
|
18
18
|
end
|
19
19
|
|
20
20
|
task :fix_perms do
|
data/TODO
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Patches and pull-requests (by [public]{mailto:mogile@googlegroups.com} or
|
2
|
+
[private email]{mailto:normalperson@yhbt.net}) greatly appreciated!
|
3
|
+
|
4
|
+
* MogileFS::Admin needs to be fleshed out
|
5
|
+
|
6
|
+
* optional Cool.io support
|
7
|
+
|
8
|
+
* optional EventMachine support
|
9
|
+
|
10
|
+
* manpage for "mog"
|
data/bin/mog
CHANGED
@@ -1,24 +1,33 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'mogilefs'
|
3
3
|
require 'optparse'
|
4
|
-
|
4
|
+
$stdin.binmode
|
5
|
+
$stdout.binmode
|
6
|
+
$stderr.sync = $stdout.sync = true
|
5
7
|
|
6
8
|
trap('INT') { exit 130 }
|
7
9
|
trap('PIPE') { exit 0 }
|
10
|
+
if md5_trailer_nodes = ENV["MD5_TRAILER_NODES"]
|
11
|
+
md5_trailer_nodes.split(/\s*,\s*/).each do |host|
|
12
|
+
MogileFS::HTTPFile::MD5_TRAILER_NODES[host] = true
|
13
|
+
end
|
14
|
+
end
|
8
15
|
|
9
16
|
# this is to be compatible with config files used by the Perl tools
|
10
17
|
def parse_config_file!(path, overwrite = false)
|
11
18
|
dest = {}
|
12
19
|
File.open(path).each_line do |line|
|
13
|
-
line
|
14
|
-
|
20
|
+
case line
|
21
|
+
when /^(domain|class)\s*=\s*(\S+)/
|
15
22
|
dest[$1.to_sym] = $2
|
16
|
-
|
23
|
+
when /^(?:trackers|hosts)\s*=\s*(.*)/
|
17
24
|
dest[:hosts] = $1.split(/\s*,\s*/)
|
18
|
-
|
19
|
-
dest[:timeout] =
|
25
|
+
when /^timeout\s*=\s*(.*)/
|
26
|
+
dest[:timeout] = $1.to_f
|
27
|
+
when /^noclobber\s*=\s*true\s*/
|
28
|
+
dest[:noclobber] = true
|
20
29
|
else
|
21
|
-
|
30
|
+
warn "Ignored configuration line: #{line}" unless /^#/.match(line)
|
22
31
|
end
|
23
32
|
end
|
24
33
|
dest
|
@@ -33,6 +42,7 @@ cli_cfg = {}
|
|
33
42
|
config_file = nil
|
34
43
|
ls_l = false
|
35
44
|
ls_h = false
|
45
|
+
chunk = false
|
36
46
|
test = {}
|
37
47
|
cat = { :raw => false }
|
38
48
|
|
@@ -50,15 +60,19 @@ ARGV.options do |x|
|
|
50
60
|
|
51
61
|
x.on('-e', 'True if key exists') { test[:e] = true }
|
52
62
|
x.on('-r', '--raw', 'show raw big_info file information') { cat[:raw] = true }
|
63
|
+
x.on('-n', '--no-clobber', 'do not clobber existing key') do
|
64
|
+
cli_cfg[:noclobber] = true
|
65
|
+
end
|
53
66
|
|
54
67
|
x.on('-C', '--class=s', 'class') { |klass| cli_cfg[:class] = klass }
|
55
68
|
x.on('-d', '--domain=s', 'domain') { |domain| cli_cfg[:domain] = domain }
|
56
69
|
x.on('-l', "long listing format (`ls' command)") { ls_l = true }
|
57
70
|
x.on('-h', '--human-readable',
|
58
71
|
"print sizes in human-readable format (`ls' command)") { ls_h = true }
|
59
|
-
|
72
|
+
x.on('--chunk', "chunk uploads (`tee' command)") { chunk = true }
|
60
73
|
x.separator ''
|
61
74
|
x.on('--help', 'Show this help message.') { puts x; exit }
|
75
|
+
x.on('--version', 'Show --version') { puts "#$0 #{MogileFS::VERSION}"; exit }
|
62
76
|
x.parse!
|
63
77
|
end
|
64
78
|
|
@@ -86,18 +100,17 @@ err = []
|
|
86
100
|
err << "trackers must be specified" if cfg[:hosts].nil? || cfg[:hosts].empty?
|
87
101
|
err << "domain must be specified" unless cfg[:domain]
|
88
102
|
if err.any?
|
89
|
-
|
90
|
-
|
103
|
+
warn "Errors:\n #{err.join("\n ")}"
|
104
|
+
warn ARGV.options
|
91
105
|
exit 1
|
92
106
|
end
|
93
107
|
|
94
108
|
unless cmd = ARGV.shift
|
95
|
-
|
109
|
+
warn ARGV.options
|
96
110
|
exit 1
|
97
111
|
end
|
98
112
|
|
99
113
|
cfg[:timeout] ||= 30 # longer timeout for interactive use
|
100
|
-
include MogileFS::Util
|
101
114
|
mg = MogileFS::MogileFS.new(cfg)
|
102
115
|
|
103
116
|
def store_file_retry(mg, key, storage_class, filepath)
|
@@ -107,56 +120,57 @@ def store_file_retry(mg, key, storage_class, filepath)
|
|
107
120
|
rescue MogileFS::UnreadableSocketError,
|
108
121
|
MogileFS::Backend::NoDevicesError => err
|
109
122
|
if ((tries += 1) < 10)
|
110
|
-
|
123
|
+
warn "Retrying on error: #{err}: #{err.message} tries: #{tries}"
|
111
124
|
retry
|
112
125
|
else
|
113
|
-
|
126
|
+
warn "FATAL: #{err}: #{err.message} tries: #{tries}"
|
114
127
|
end
|
115
128
|
exit 1
|
116
129
|
end
|
117
130
|
end
|
118
131
|
|
132
|
+
def human_size(size)
|
133
|
+
suff = ''
|
134
|
+
%w(K M G).each do |s|
|
135
|
+
size /= 1024.0
|
136
|
+
if size <= 1024
|
137
|
+
suff = s
|
138
|
+
break
|
139
|
+
end
|
140
|
+
end
|
141
|
+
sprintf("%.1f%s", size, suff)
|
142
|
+
end
|
143
|
+
|
119
144
|
begin
|
120
145
|
case cmd
|
121
146
|
when 'cp'
|
122
147
|
filename = ARGV.shift or raise ArgumentError, '<filename> <key>'
|
123
|
-
|
148
|
+
dkey = ARGV.shift or raise ArgumentError, '<filename> <key>'
|
124
149
|
ARGV.shift and raise ArgumentError, '<filename> <key>'
|
125
|
-
|
150
|
+
cfg[:noclobber] && mg.exist?(dkey) and
|
151
|
+
abort "`#{dkey}' already exists and -n/--no-clobber was specified"
|
152
|
+
store_file_retry(mg, dkey, cfg[:class], filename)
|
126
153
|
when 'cat'
|
127
154
|
ARGV.empty? and raise ArgumentError, '<key1> [<key2> ...]'
|
128
155
|
ARGV.each do |key|
|
129
156
|
if (!cat[:raw] && key =~ /^_big_info:/)
|
130
|
-
mg.bigfile_write(key,
|
157
|
+
mg.bigfile_write(key, $stdout, {:verify => true})
|
131
158
|
else
|
132
|
-
mg.get_file_data(key
|
159
|
+
mg.get_file_data(key, $stdout)
|
133
160
|
end
|
134
161
|
end
|
135
162
|
when 'ls'
|
136
163
|
prefixes = ARGV.empty? ? [ nil ] : ARGV
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
if ls_h && size > 1024
|
143
|
-
suff = ''
|
144
|
-
%w(K M G).each do |s|
|
145
|
-
size /= 1024.0
|
146
|
-
suff = s
|
147
|
-
break if size <= 1024
|
148
|
-
end
|
149
|
-
size = sprintf("%.1f%s", size, suff)
|
150
|
-
else
|
151
|
-
size = size.to_s
|
152
|
-
end
|
153
|
-
size = (' ' * (12 - size.length)) << size # right justify
|
154
|
-
puts [ path_nr, size, key ].pack("A4 A16 A32")
|
155
|
-
else
|
156
|
-
puts key
|
157
|
-
end
|
164
|
+
if ls_l
|
165
|
+
each_key = lambda do |key, size, devcount|
|
166
|
+
size = ls_h && size > 1024 ? human_size(size) : size.to_s
|
167
|
+
size = (' ' * (12 - size.length)) << size # right justify
|
168
|
+
puts [ sprintf("% 2d", devcount), size, key ].pack("A4 A16 A*")
|
158
169
|
end
|
170
|
+
else
|
171
|
+
each_key = lambda { |key| puts key }
|
159
172
|
end
|
173
|
+
prefixes.each { |prefix| mg.each_key(prefix, &each_key) }
|
160
174
|
when 'rm'
|
161
175
|
ARGV.empty? and raise ArgumentError, '<key1> [<key2>]'
|
162
176
|
ARGV.each { |key| mg.delete(key) }
|
@@ -167,35 +181,67 @@ begin
|
|
167
181
|
mg.rename(from, to)
|
168
182
|
when 'stat' # this outputs a RFC822-like format
|
169
183
|
ARGV.empty? and raise ArgumentError, '<key1> [<key2>]'
|
170
|
-
|
171
|
-
|
184
|
+
ok = true
|
185
|
+
ARGV.each_with_index do |key,j|
|
186
|
+
begin
|
187
|
+
info = mg.file_info(key)
|
172
188
|
puts "Key: #{key}"
|
173
|
-
puts "Size: #{
|
174
|
-
|
189
|
+
puts "Size: #{info['length']}"
|
190
|
+
puts "Class: #{info['class']}"
|
191
|
+
o = { :pathcount => info["devcount"] }
|
192
|
+
mg.get_paths(key, o).each_with_index do |path,i|
|
175
193
|
puts "URL-#{i}: #{path}"
|
176
194
|
end
|
177
|
-
puts ""
|
178
|
-
|
179
|
-
|
195
|
+
puts "" if ARGV.size != (j + 1)
|
196
|
+
rescue MogileFS::Backend::UnknownKeyError
|
197
|
+
warn "No such key: #{key}"
|
198
|
+
ok = false
|
180
199
|
end
|
181
200
|
end
|
201
|
+
exit(ok)
|
182
202
|
when 'tee'
|
183
203
|
require 'tempfile'
|
184
|
-
|
204
|
+
dkey = ARGV.shift or raise ArgumentError, '<key>'
|
185
205
|
ARGV.shift and raise ArgumentError, '<key>'
|
186
|
-
cfg[:
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
206
|
+
cfg[:noclobber] && mg.exist?(dkey) and
|
207
|
+
abort "`#{dkey}' already exists and -n/--no-clobber was specified"
|
208
|
+
skip_tee = File.stat('/dev/null') == $stdout.stat
|
209
|
+
|
210
|
+
if chunk
|
211
|
+
if skip_tee
|
212
|
+
tee_obj = $stdin
|
213
|
+
else
|
214
|
+
tee_obj = lambda do |*args|
|
215
|
+
buf = $stdin.readpartial(*args)
|
216
|
+
$stdout.write(buf)
|
217
|
+
buf
|
218
|
+
end
|
219
|
+
class << tee_obj
|
220
|
+
alias readpartial call
|
221
|
+
end
|
222
|
+
end
|
223
|
+
mg.store_file(dkey, cfg[:class], tee_obj)
|
224
|
+
else # buffer input, first
|
225
|
+
tmp = Tempfile.new('mog-tee')
|
226
|
+
tmp.sync = true
|
227
|
+
|
228
|
+
# if stdout is pointing to /dev/null, don't bother installing the filter.
|
229
|
+
tee_obj = tmp
|
230
|
+
unless skip_tee
|
231
|
+
tee_obj = lambda do |buf|
|
232
|
+
$stdout.write(buf)
|
233
|
+
tmp.write(buf)
|
234
|
+
end
|
235
|
+
class << tee_obj
|
236
|
+
alias write call
|
237
|
+
end
|
238
|
+
end
|
239
|
+
begin
|
240
|
+
MogileFS.io.copy_stream($stdin, tee_obj)
|
241
|
+
store_file_retry(mg, dkey, cfg[:class], tmp.path)
|
242
|
+
ensure
|
243
|
+
tmp.close!
|
244
|
+
end
|
199
245
|
end
|
200
246
|
when 'test'
|
201
247
|
truth, ok = true, nil
|
@@ -213,20 +259,15 @@ begin
|
|
213
259
|
raise ArgumentError, "Too many arguments"
|
214
260
|
end
|
215
261
|
|
216
|
-
|
217
|
-
|
218
|
-
ok = !!(paths && paths.size > 0)
|
219
|
-
else
|
220
|
-
raise ArgumentError, "Unknown flag: -#{test.keys.first}"
|
221
|
-
end
|
222
|
-
|
262
|
+
test[:e] or raise ArgumentError, "Unknown flag: -#{test.keys.first}"
|
263
|
+
ok = mg.exist?(key)
|
223
264
|
truth or ok = ! ok
|
224
265
|
exit ok ? 0 : 1
|
225
266
|
else
|
226
267
|
raise ArgumentError, "Unknown command: #{cmd}"
|
227
268
|
end
|
228
269
|
rescue ArgumentError => err
|
229
|
-
|
270
|
+
warn "Usage: #{$0} #{cmd} #{err.message}"
|
230
271
|
exit 1
|
231
272
|
end
|
232
273
|
exit 0
|