mogilefs-client 2.2.0 → 3.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|