libgfapi-ruby 0.0.7 → 0.0.8
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.
- checksums.yaml +4 -4
- data/README.md +11 -2
- data/lib/glusterfs/bindings.rb +22 -0
- data/lib/glusterfs/dirent.rb +7 -0
- data/lib/glusterfs/version.rb +1 -1
- data/lib/glusterfs/volume.rb +42 -5
- data/lib/glusterfs.rb +2 -1
- data/spec/glusterfs/{memleak_spec.rb → stress/memleak_spec.rb} +17 -15
- data/spec/glusterfs/volume_spec.rb +59 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2cf4e28e5936b345b94a5b64495a3aee76b48e6
|
4
|
+
data.tar.gz: 52d88565ff4b52182ec47e0d7495b4eca46df4ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64da0439a3d8bedf46943b3a98dba14ad1b1938a53871f6489f47df036cb711b165a318513689b030ce15bf5eea59aa0e9569c2d9307e1cd3abbca4ce8c432b8
|
7
|
+
data.tar.gz: d85a6a1eea2c1fc5609a17c8217a0f41cb52598284bbde20db89aabbc21d6c49e67be55b96574b20f4a066bd1fff2d12d53df67abccb810d9bbda049dbb2f636
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Ruby bindings for [libgfapi](https://github.com/gluster/glusterfs/blob/master/ap
|
|
5
5
|
|
6
6
|
## Warning
|
7
7
|
|
8
|
-
This library is currently under active development, and
|
8
|
+
This library is currently under active development, and API may break often.
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -37,6 +37,8 @@ dir.create
|
|
37
37
|
# Delete a directory
|
38
38
|
dir = GlusterDS::Directory.new(volume, '/some_dir')
|
39
39
|
dir.delete
|
40
|
+
# or
|
41
|
+
volume.delete_dir('/some_dir')
|
40
42
|
|
41
43
|
# Create a file from string or bytes
|
42
44
|
file = GlusterFS::File.new(volume, '/gfs/file/path')
|
@@ -60,7 +62,9 @@ puts "Tempfile path: #{tempfile.path}"
|
|
60
62
|
|
61
63
|
# Delete a file
|
62
64
|
file = GlusterFS::File.new(volume, '/gfs/file/path')
|
63
|
-
file.
|
65
|
+
file.delete
|
66
|
+
# or
|
67
|
+
volume.delete_file('/gfs/file/path')
|
64
68
|
|
65
69
|
# Unmount virtual mount
|
66
70
|
volume.unmount
|
@@ -85,6 +89,11 @@ export GFS_SERVER_PORT=24007
|
|
85
89
|
rake spec
|
86
90
|
```
|
87
91
|
|
92
|
+
## TODO
|
93
|
+
|
94
|
+
Major things missing:
|
95
|
+
- Directory listing
|
96
|
+
|
88
97
|
## Contributing
|
89
98
|
|
90
99
|
1. Fork it ( http://github.com/spajus/libgfapi-ruby/fork )
|
data/lib/glusterfs/bindings.rb
CHANGED
@@ -338,6 +338,28 @@ module GlusterFS
|
|
338
338
|
=end
|
339
339
|
attach_function :lstat, :glfs_lstat, [:pointer, :string, :pointer], :int
|
340
340
|
|
341
|
+
=begin
|
342
|
+
glfs_fd_t *glfs_opendir (glfs_t *fs, const char *path) __THROW;
|
343
|
+
=end
|
344
|
+
attach_function :opendir, :glfs_opendir, [:pointer, :string], :pointer
|
345
|
+
|
346
|
+
=begin
|
347
|
+
int glfs_closedir (glfs_fd_t *fd) __THROW;
|
348
|
+
=end
|
349
|
+
attach_function :closedir, :glfs_closedir, [:pointer], :int
|
350
|
+
|
351
|
+
=begin
|
352
|
+
@glfs_readdir_r and @glfs_readdirplus_r ARE thread safe AND re-entrant,
|
353
|
+
but the interface has ambiguity about the size of @dirent to be allocated
|
354
|
+
before calling the APIs. 512 byte buffer (for @dirent) is sufficient for
|
355
|
+
all known systems which are tested againt glusterfs/gfapi, but may be
|
356
|
+
insufficient in the future.
|
357
|
+
|
358
|
+
int glfs_readdir_r (glfs_fd_t *fd, struct dirent *dirent,
|
359
|
+
struct dirent **result) __THROW;
|
360
|
+
=end
|
361
|
+
attach_function :readdir_r, :glfs_readdir_r, [:pointer, :pointer, :pointer], :int
|
362
|
+
|
341
363
|
# TODO the rest
|
342
364
|
|
343
365
|
end
|
data/lib/glusterfs/version.rb
CHANGED
data/lib/glusterfs/volume.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class GlusterFS::Volume
|
2
|
-
attr_reader :name, :fs, :mounted
|
2
|
+
attr_reader :name, :fs, :mounted, :protocol, :host, :port
|
3
3
|
|
4
4
|
def initialize(name)
|
5
5
|
@name = name
|
@@ -8,16 +8,39 @@ class GlusterFS::Volume
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def mount(host, port = 24007, protocol = 'tcp')
|
11
|
+
raise GlusterFS::Error, "Already mounted: #{self}" if mounted?
|
11
12
|
GlusterFS.set_volfile_server(@fs, protocol, host, port)
|
12
13
|
result = GlusterFS.init(@fs)
|
13
|
-
if result != 0
|
14
|
-
raise GlusterFS::Error,
|
15
|
-
"Failed to mount volume '#{volume_name}' on #{protocol}://#{host}:#{port}"
|
16
|
-
end
|
14
|
+
raise GlusterFS::Error, "Failed to mount volume #{self}" if result != 0
|
17
15
|
@mounted = true
|
16
|
+
@host = host
|
17
|
+
@protocol = protocol
|
18
|
+
@port = port
|
18
19
|
self
|
19
20
|
end
|
20
21
|
|
22
|
+
def lstat(path)
|
23
|
+
check_mounted
|
24
|
+
data = GlusterFS::Stat.new
|
25
|
+
GlusterFS.lstat(@fs, path, data)
|
26
|
+
data
|
27
|
+
end
|
28
|
+
|
29
|
+
def list(path)
|
30
|
+
dir = Directory.new(volume, path)
|
31
|
+
dir.list
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete_file(path)
|
35
|
+
check_mounted
|
36
|
+
GlusterFS.unlink(@fs, path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_dir(path)
|
40
|
+
check_mounted
|
41
|
+
GlusterFS.rmdir(@fs, path)
|
42
|
+
end
|
43
|
+
|
21
44
|
def mounted?
|
22
45
|
@mounted
|
23
46
|
end
|
@@ -29,4 +52,18 @@ class GlusterFS::Volume
|
|
29
52
|
true
|
30
53
|
end
|
31
54
|
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
if mounted?
|
60
|
+
"GlusterFS::Volume['#{@name}' on #{protocol}://#{host}:#{port}]"
|
61
|
+
else
|
62
|
+
"GlusterFS::Volume['#{@name}' (unmounted)]"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def check_mounted
|
67
|
+
raise GlusterFS::Error, "Volume not mounted: #{self}" unless mounted?
|
68
|
+
end
|
32
69
|
end
|
data/lib/glusterfs.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require "ffi"
|
2
2
|
require "glusterfs/version"
|
3
|
+
require "glusterfs/dirent"
|
4
|
+
require "glusterfs/stat"
|
3
5
|
require "glusterfs/bindings"
|
4
6
|
require "glusterfs/error"
|
5
7
|
require "glusterfs/file"
|
6
8
|
require "glusterfs/directory"
|
7
9
|
require "glusterfs/volume"
|
8
|
-
require "glusterfs/stat"
|
9
10
|
|
10
11
|
module GlusterFS
|
11
12
|
end
|
@@ -1,26 +1,28 @@
|
|
1
1
|
require 'ruby-mass'
|
2
2
|
module GlusterFS
|
3
3
|
|
4
|
+
# Set MEM_PRINT=1 MEM_ITERATIONS=10000 to get a stress test
|
5
|
+
|
4
6
|
def self.mem_size
|
5
|
-
# ObjectSpace.garbage_collect
|
6
|
-
# sleep 3
|
7
7
|
_, size = `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)
|
8
8
|
size.to_i
|
9
9
|
end
|
10
10
|
|
11
11
|
describe 'memleaks' do
|
12
12
|
|
13
|
-
let(:iterations) {
|
13
|
+
let(:iterations) { (ENV['MEM_ITERATIONS'] || 100).to_i }
|
14
14
|
|
15
15
|
before(:all) do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
if ENV['MEM_PRINT']
|
17
|
+
puts "GC Settings"
|
18
|
+
puts "RUBY_HEAP_MIN_SLOTS=#{ENV['RUBY_HEAP_MIN_SLOTS']}"
|
19
|
+
puts "RUBY_HEAP_SLOTS_INCREMENT=#{ENV['RUBY_HEAP_SLOTS_INCREMENT']}"
|
20
|
+
puts "RUBY_HEAP_SLOTS_GROWTH_FACTOR=#{ENV['RUBY_HEAP_SLOTS_GROWTH_FACTOR']}"
|
21
|
+
puts "RUBY_GC_MALLOC_LIMIT=#{ENV['RUBY_GC_MALLOC_LIMIT']}"
|
22
|
+
puts "RUBY_FREE_MIN=#{ENV['RUBY_FREE_MIN']}"
|
23
|
+
puts "Initial memory use: #{GlusterFS.mem_size}"
|
24
|
+
Mass.print
|
25
|
+
end
|
24
26
|
end
|
25
27
|
|
26
28
|
let(:random_blob) do
|
@@ -35,7 +37,7 @@ module GlusterFS
|
|
35
37
|
before { root_dir.create }
|
36
38
|
after { root_dir.delete }
|
37
39
|
specify do
|
38
|
-
puts "Iterations: #{iterations}"
|
40
|
+
puts "Dir Iterations: #{iterations}"
|
39
41
|
mem_size_before = GlusterFS.mem_size
|
40
42
|
iterations.times do |i|
|
41
43
|
dir = Directory.new(volume, "#{root_dir.path}/subdir-#{i}")
|
@@ -44,7 +46,7 @@ module GlusterFS
|
|
44
46
|
end
|
45
47
|
mem_size = GlusterFS.mem_size
|
46
48
|
puts "Mem growth: #{mem_size - mem_size_before}"
|
47
|
-
Mass.print
|
49
|
+
Mass.print if ENV['MEM_PRINT']
|
48
50
|
(mem_size - mem_size_before).should be < 10240
|
49
51
|
end
|
50
52
|
end
|
@@ -53,7 +55,7 @@ module GlusterFS
|
|
53
55
|
before { root_dir.create }
|
54
56
|
after { root_dir.delete }
|
55
57
|
specify do
|
56
|
-
puts "Iterations: #{iterations}"
|
58
|
+
puts "File Iterations: #{iterations}"
|
57
59
|
mem_size_before = GlusterFS.mem_size
|
58
60
|
iterations.times do |i|
|
59
61
|
file = File.new(volume, "#{root_dir.path}/file-#{i}")
|
@@ -62,7 +64,7 @@ module GlusterFS
|
|
62
64
|
end
|
63
65
|
mem_size = GlusterFS.mem_size
|
64
66
|
puts "Mem growth: #{mem_size - mem_size_before}"
|
65
|
-
Mass.print
|
67
|
+
Mass.print if ENV['MEM_PRINT']
|
66
68
|
(mem_size - mem_size_before).should be < 10240
|
67
69
|
end
|
68
70
|
end
|
@@ -4,6 +4,8 @@ module GlusterFS
|
|
4
4
|
describe Volume do
|
5
5
|
let(:volume) { Volume.new(GFS_VOLUME) }
|
6
6
|
|
7
|
+
after(:each) { volume.unmount if volume.mounted? }
|
8
|
+
|
7
9
|
context '#mount' do
|
8
10
|
before { volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT) }
|
9
11
|
subject { volume.mounted? }
|
@@ -19,7 +21,64 @@ module GlusterFS
|
|
19
21
|
it { should_not be_true }
|
20
22
|
end
|
21
23
|
|
24
|
+
context '#lstat' do
|
25
|
+
context 'on file' do
|
26
|
+
let(:file_name) { "test-stat-#{Time.now.to_i}" }
|
27
|
+
let(:file) { File.new(volume, file_name) }
|
28
|
+
let(:data) { '123' }
|
29
|
+
before do
|
30
|
+
volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
|
31
|
+
file.write(data)
|
32
|
+
end
|
33
|
+
after { file.delete }
|
34
|
+
subject { volume.lstat(file.path) }
|
35
|
+
its([:st_size]) { should == file.size }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'on directory' do
|
39
|
+
let(:dir_name) { "test-#{Time.now.to_i}" }
|
40
|
+
let(:dir) { Directory.new(volume, dir_name) }
|
41
|
+
before do
|
42
|
+
volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
|
43
|
+
dir.create
|
44
|
+
end
|
45
|
+
after { dir.delete }
|
46
|
+
subject { volume.lstat(dir.path) }
|
47
|
+
its([:st_blksize]) { should == dir.lstat[:st_blksize] }
|
48
|
+
end
|
49
|
+
|
50
|
+
specify 'raise error when unmounted' do
|
51
|
+
expect { volume.lstat('/foo/bar') }.to raise_error(GlusterFS::Error)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context '#delete_dir' do
|
56
|
+
let(:dir_name) { "test-#{Time.now.to_i}" }
|
57
|
+
let(:dir) { Directory.new(volume, dir_name) }
|
58
|
+
before do
|
59
|
+
volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
|
60
|
+
dir.create
|
61
|
+
end
|
62
|
+
before { volume.delete_dir(dir.path) }
|
63
|
+
subject { dir.exists? }
|
64
|
+
it { should_not be_true }
|
65
|
+
end
|
66
|
+
|
67
|
+
context '#delete_file' do
|
68
|
+
let(:file_name) { "test-stat-#{Time.now.to_i}" }
|
69
|
+
let(:file) { File.new(volume, file_name) }
|
70
|
+
let(:data) { '123' }
|
71
|
+
before do
|
72
|
+
volume.mount(GFS_SERVER_HOST, GFS_SERVER_PORT)
|
73
|
+
file.write(data)
|
74
|
+
end
|
75
|
+
before { volume.delete_file(file.path) }
|
76
|
+
subject { file.exists? }
|
77
|
+
it { should_not be_true }
|
78
|
+
end
|
79
|
+
|
22
80
|
context '#mounted?' do
|
81
|
+
before { volume.unmount }
|
23
82
|
subject { volume.mounted? }
|
24
83
|
|
25
84
|
context 'on mounted volume' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libgfapi-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas Varaneckas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -95,6 +95,7 @@ files:
|
|
95
95
|
- lib/glusterfs.rb
|
96
96
|
- lib/glusterfs/bindings.rb
|
97
97
|
- lib/glusterfs/directory.rb
|
98
|
+
- lib/glusterfs/dirent.rb
|
98
99
|
- lib/glusterfs/error.rb
|
99
100
|
- lib/glusterfs/file.rb
|
100
101
|
- lib/glusterfs/stat.rb
|
@@ -103,7 +104,7 @@ files:
|
|
103
104
|
- libgfapi-ruby.gemspec
|
104
105
|
- spec/glusterfs/directory_spec.rb
|
105
106
|
- spec/glusterfs/file_spec.rb
|
106
|
-
- spec/glusterfs/memleak_spec.rb
|
107
|
+
- spec/glusterfs/stress/memleak_spec.rb
|
107
108
|
- spec/glusterfs/volume_spec.rb
|
108
109
|
- spec/spec_helper.rb
|
109
110
|
homepage: https://github.com/spajus/libgfapi-ruby
|
@@ -133,7 +134,7 @@ summary: Ruby bindings for libgfapi (GlusterFS API)
|
|
133
134
|
test_files:
|
134
135
|
- spec/glusterfs/directory_spec.rb
|
135
136
|
- spec/glusterfs/file_spec.rb
|
136
|
-
- spec/glusterfs/memleak_spec.rb
|
137
|
+
- spec/glusterfs/stress/memleak_spec.rb
|
137
138
|
- spec/glusterfs/volume_spec.rb
|
138
139
|
- spec/spec_helper.rb
|
139
140
|
has_rdoc:
|