libgfapi-ruby 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +17 -10
- data/Rakefile +5 -0
- data/lib/glusterfs.rb +7 -335
- data/lib/glusterfs/bindings.rb +343 -0
- data/lib/glusterfs/client.rb +13 -0
- data/lib/glusterfs/directory.rb +2 -0
- data/lib/glusterfs/error.rb +2 -0
- data/lib/glusterfs/file.rb +63 -18
- data/lib/glusterfs/stat.rb +18 -0
- data/lib/glusterfs/version.rb +1 -1
- data/lib/glusterfs/volume.rb +30 -0
- data/libgfapi-ruby.gemspec +2 -0
- data/spec/glusterfs/client_spec.rb +10 -0
- data/spec/glusterfs/file_spec.rb +153 -0
- data/spec/spec_helper.rb +13 -0
- metadata +42 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 218fc8b79c32f5db3573e1714cba7376906d2328
|
4
|
+
data.tar.gz: fa6b48a3b70348aa703cc68cbee7a2802ae52f92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7804714a56eaf5364e9fb24cfd86d3f278ef92ef835b3356a60e29572d88b18d2257b37cb8387a023f27ae4cdc3135afe2991bf83d5069810c9757aaad550b90
|
7
|
+
data.tar.gz: 0c31210229bc5b178e2a586507f49da15e6616eee3496ecfe2d61370aae72c60f07795052fd2e689db4b60dc21a43f5ad915c9ea3592e7a0802aaf980bae935f
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
Ruby bindings for [libgfapi](https://github.com/gluster/glusterfs/blob/master/api/src/glfs.h)
|
4
4
|
(GlusterFS API).
|
5
5
|
|
6
|
+
## Warning
|
7
|
+
|
8
|
+
This library is currently under active development, and is not ready for production yet.
|
9
|
+
|
6
10
|
## Installation
|
7
11
|
|
8
12
|
Add this line to your application's Gemfile:
|
@@ -23,24 +27,27 @@ Or install it yourself as:
|
|
23
27
|
require 'glusterfs'
|
24
28
|
|
25
29
|
# Create virtual mount
|
26
|
-
|
27
|
-
GlusterFS.set_volfile_server fs, 'tcp', '1.2.3.4', 24007
|
28
|
-
GlusterFS.init fs
|
30
|
+
volume = GlusterFS::Client.mount('my_volume', '1.2.3.4')
|
29
31
|
|
30
|
-
# Make a new directory
|
31
|
-
GlusterFS.mkdir
|
32
|
+
# Make a new directory (raw)
|
33
|
+
GlusterFS.mkdir(volume.fs, '/some_dir', 0755)
|
32
34
|
|
33
35
|
# Write a file
|
34
|
-
file = File.
|
35
|
-
size =
|
36
|
+
file = GlusterFS::File.new(volume, '/gfs/file/path')
|
37
|
+
size = file.write(data)
|
36
38
|
puts "Written #{size} bytes"
|
37
39
|
|
38
40
|
# Read a file
|
39
|
-
file = GlusterFS::File.
|
41
|
+
file = GlusterFS::File.new(volume, '/gfs/file/path')
|
40
42
|
contents = file.read
|
43
|
+
contents = file.read
|
44
|
+
|
45
|
+
# Delete a file
|
46
|
+
file = GlusterFS::File.new(volume, '/gfs/file/path')
|
47
|
+
file.unlink
|
41
48
|
|
42
|
-
#
|
43
|
-
|
49
|
+
# Unmount virtual mount
|
50
|
+
volume.unmount
|
44
51
|
```
|
45
52
|
|
46
53
|
## Contributing
|
data/Rakefile
CHANGED
data/lib/glusterfs.rb
CHANGED
@@ -1,340 +1,12 @@
|
|
1
|
+
require "ffi"
|
1
2
|
require "glusterfs/version"
|
3
|
+
require "glusterfs/bindings"
|
4
|
+
require "glusterfs/error"
|
2
5
|
require "glusterfs/file"
|
3
|
-
require "
|
6
|
+
require "glusterfs/directory"
|
7
|
+
require "glusterfs/volume"
|
8
|
+
require "glusterfs/client"
|
9
|
+
require "glusterfs/stat"
|
4
10
|
|
5
11
|
module GlusterFS
|
6
|
-
extend FFI::Library
|
7
|
-
|
8
|
-
# https://github.com/gluster/glusterfs/blob/master/api/src/glfs.h
|
9
|
-
ffi_lib 'gfapi'
|
10
|
-
|
11
|
-
=begin
|
12
|
-
SYNOPSIS
|
13
|
-
|
14
|
-
glfs_new: Create a new 'virtual mount' object.
|
15
|
-
|
16
|
-
DESCRIPTION
|
17
|
-
|
18
|
-
This is most likely the very first function you will use. This function
|
19
|
-
will create a new glfs_t (virtual mount) object in memory.
|
20
|
-
|
21
|
-
On this newly created glfs_t, you need to be either set a volfile path
|
22
|
-
(glfs_set_volfile) or a volfile server (glfs_set_volfile_server).
|
23
|
-
|
24
|
-
The glfs_t object needs to be initialized with glfs_init() before you
|
25
|
-
can start issuing file operations on it.
|
26
|
-
|
27
|
-
PARAMETERS
|
28
|
-
|
29
|
-
@volname: Name of the volume. This identifies the server-side volume and
|
30
|
-
the fetched volfile (equivalent of --volfile-id command line
|
31
|
-
parameter to glusterfsd). When used with glfs_set_volfile() the
|
32
|
-
@volname has no effect (except for appearing in log messages).
|
33
|
-
|
34
|
-
RETURN VALUES
|
35
|
-
|
36
|
-
NULL : Out of memory condition.
|
37
|
-
Others : Pointer to the newly created glfs_t virtual mount object.
|
38
|
-
|
39
|
-
glfs_t *glfs_new (const char *volname) __THROW;
|
40
|
-
=end
|
41
|
-
attach_function :new, :glfs_new, [:string], :pointer
|
42
|
-
|
43
|
-
=begin
|
44
|
-
SYNOPSIS
|
45
|
-
|
46
|
-
glfs_set_volfile: Specify the path to the volume specification file.
|
47
|
-
|
48
|
-
DESCRIPTION
|
49
|
-
|
50
|
-
If you are using a static volume specification file (without dynamic
|
51
|
-
volume management abilities from the CLI), then specify the path to
|
52
|
-
the volume specification file.
|
53
|
-
|
54
|
-
This is incompatible with glfs_set_volfile_server().
|
55
|
-
|
56
|
-
PARAMETERS
|
57
|
-
|
58
|
-
@fs: The 'virtual mount' object to be configured with the volume
|
59
|
-
specification file.
|
60
|
-
|
61
|
-
@volfile: Path to the locally available volume specification file.
|
62
|
-
|
63
|
-
RETURN VALUES
|
64
|
-
|
65
|
-
0 : Success.
|
66
|
-
-1 : Failure. @errno will be set with the type of failure.
|
67
|
-
|
68
|
-
int glfs_set_volfile (glfs_t *fs, const char *volfile);
|
69
|
-
=end
|
70
|
-
attach_function :set_volfile, :glfs_set_volfile, [:pointer, :string], :int
|
71
|
-
|
72
|
-
=begin
|
73
|
-
SYNOPSIS
|
74
|
-
|
75
|
-
glfs_set_volfile_server: Specify the address of management server.
|
76
|
-
|
77
|
-
DESCRIPTION
|
78
|
-
|
79
|
-
This function specifies the address of the management server (glusterd)
|
80
|
-
to connect, and establish the volume configuration. The @volname
|
81
|
-
parameter passed to glfs_new() is the volume which will be virtually
|
82
|
-
mounted as the glfs_t object. All operations performed by the CLI at
|
83
|
-
the management server will automatically be reflected in the 'virtual
|
84
|
-
mount' object as it maintains a connection to glusterd and polls on
|
85
|
-
configuration change notifications.
|
86
|
-
|
87
|
-
This is incompatible with glfs_set_volfile().
|
88
|
-
|
89
|
-
PARAMETERS
|
90
|
-
|
91
|
-
@fs: The 'virtual mount' object to be configured with the volume
|
92
|
-
specification file.
|
93
|
-
|
94
|
-
@transport: String specifying the transport used to connect to the
|
95
|
-
management daemon. Specifying NULL will result in the usage
|
96
|
-
of the default (tcp) transport type. Permitted values
|
97
|
-
are those what you specify as transport-type in a volume
|
98
|
-
specification file (e.g "tcp", "rdma", "unix".)
|
99
|
-
|
100
|
-
@host: String specifying the address of where to find the management
|
101
|
-
daemon. Depending on the transport type this would either be
|
102
|
-
an FQDN (e.g: "storage01.company.com"), ASCII encoded IP
|
103
|
-
address "192.168.22.1", or a UNIX domain socket path (e.g
|
104
|
-
"/tmp/glusterd.socket".)
|
105
|
-
|
106
|
-
@port: The TCP port number where gluster management daemon is listening.
|
107
|
-
Specifying 0 uses the default port number GF_DEFAULT_BASE_PORT.
|
108
|
-
This parameter is unused if you are using a UNIX domain socket.
|
109
|
-
|
110
|
-
RETURN VALUES
|
111
|
-
|
112
|
-
0 : Success.
|
113
|
-
-1 : Failure. @errno will be set with the type of failure.
|
114
|
-
|
115
|
-
int glfs_set_volfile_server (glfs_t *fs, const char *transport,
|
116
|
-
const char *host, int port) __THROW;
|
117
|
-
=end
|
118
|
-
attach_function :set_volfile_server, :glfs_set_volfile_server,
|
119
|
-
[:pointer, :string, :string, :int], :int
|
120
|
-
|
121
|
-
=begin
|
122
|
-
SYNOPSIS
|
123
|
-
|
124
|
-
glfs_set_logging: Specify logging parameters.
|
125
|
-
|
126
|
-
DESCRIPTION
|
127
|
-
|
128
|
-
This function specifies logging parameters for the virtual mount.
|
129
|
-
Default log file is /dev/null.
|
130
|
-
|
131
|
-
PARAMETERS
|
132
|
-
|
133
|
-
@fs: The 'virtual mount' object to be configured with the logging parameters.
|
134
|
-
|
135
|
-
@logfile: The logfile to be used for logging. Will be created if it does not
|
136
|
-
already exist (provided system permissions allow). If NULL, a new
|
137
|
-
logfile will be created in default log directory associated with
|
138
|
-
the glusterfs installation.
|
139
|
-
|
140
|
-
@loglevel: Numerical value specifying the degree of verbosity. Higher the
|
141
|
-
value, more verbose the logging.
|
142
|
-
|
143
|
-
RETURN VALUES
|
144
|
-
|
145
|
-
0 : Success.
|
146
|
-
-1 : Failure. @errno will be set with the type of failure.
|
147
|
-
|
148
|
-
int glfs_set_logging (glfs_t *fs, const char *logfile, int loglevel) __THROW;
|
149
|
-
=end
|
150
|
-
attach_function :set_logging, :glfs_set_logging, [:pointer, :string, :int], :int
|
151
|
-
|
152
|
-
=begin
|
153
|
-
SYNOPSIS
|
154
|
-
|
155
|
-
glfs_init: Initialize the 'virtual mount'
|
156
|
-
|
157
|
-
DESCRIPTION
|
158
|
-
|
159
|
-
This function initializes the glfs_t object. This consists of many steps:
|
160
|
-
- Spawn a poll-loop thread.
|
161
|
-
- Establish connection to management daemon and receive volume specification.
|
162
|
-
- Construct translator graph and initialize graph.
|
163
|
-
- Wait for initialization (connecting to all bricks) to complete.
|
164
|
-
|
165
|
-
PARAMETERS
|
166
|
-
|
167
|
-
@fs: The 'virtual mount' object to be initialized.
|
168
|
-
|
169
|
-
RETURN VALUES
|
170
|
-
|
171
|
-
0 : Success.
|
172
|
-
-1 : Failure. @errno will be set with the type of failure.
|
173
|
-
|
174
|
-
int glfs_init (glfs_t *fs) __THROW;
|
175
|
-
=end
|
176
|
-
attach_function :init, :glfs_init, [:pointer], :int
|
177
|
-
|
178
|
-
=begin
|
179
|
-
SYNOPSIS
|
180
|
-
|
181
|
-
glfs_fini: Cleanup and destroy the 'virtual mount'
|
182
|
-
|
183
|
-
DESCRIPTION
|
184
|
-
|
185
|
-
This function attempts to gracefully destroy glfs_t object. An attempt is
|
186
|
-
made to wait for all background processing to complete before returning.
|
187
|
-
|
188
|
-
glfs_fini() must be called after all operations on glfs_t is finished.
|
189
|
-
|
190
|
-
IMPORTANT
|
191
|
-
|
192
|
-
IT IS NECESSARY TO CALL glfs_fini() ON ALL THE INITIALIZED glfs_t
|
193
|
-
OBJECTS BEFORE TERMINATING THE PROGRAM. THERE MAY BE CACHED AND
|
194
|
-
UNWRITTEN / INCOMPLETE OPERATIONS STILL IN PROGRESS EVEN THOUGH THE
|
195
|
-
API CALLS HAVE RETURNED. glfs_fini() WILL WAIT FOR BACKGROUND OPERATIONS
|
196
|
-
TO COMPLETE BEFORE RETURNING, THEREBY MAKING IT SAFE FOR THE PROGRAM TO
|
197
|
-
EXIT.
|
198
|
-
|
199
|
-
PARAMETERS
|
200
|
-
|
201
|
-
@fs: The 'virtual mount' object to be destroyed.
|
202
|
-
|
203
|
-
RETURN VALUES
|
204
|
-
|
205
|
-
0 : Success.
|
206
|
-
|
207
|
-
int glfs_fini (glfs_t *fs) __THROW;
|
208
|
-
=end
|
209
|
-
attach_function :fini, :glfs_fini, [:pointer], :int
|
210
|
-
|
211
|
-
=begin
|
212
|
-
PER THREAD IDENTITY MODIFIERS
|
213
|
-
|
214
|
-
The following operations enable to set a per thread identity context
|
215
|
-
for the glfs APIs to perform operations as. The calls here are kept as close
|
216
|
-
to POSIX equivalents as possible.
|
217
|
-
|
218
|
-
NOTES:
|
219
|
-
|
220
|
-
- setgroups is a per thread setting, hence this is named as fsgroups to be
|
221
|
-
close in naming to the fs(u/g)id APIs
|
222
|
-
- Typical mode of operation is to set the IDs as required, with the
|
223
|
-
supplementary groups being optionally set, make the glfs call and post the
|
224
|
-
glfs operation set them back to eu/gid or uid/gid as appropriate to the
|
225
|
-
caller
|
226
|
-
- The groups once set, need to be unset by setting the size to 0 (in which
|
227
|
-
case the list argument is a do not care)
|
228
|
-
- Once a process for a thread of operation choses to set the IDs, all glfs
|
229
|
-
calls made from that thread would default to the IDs set for the thread.
|
230
|
-
As a result use these APIs with care and ensure that the set IDs are
|
231
|
-
reverted to global process defaults as required.
|
232
|
-
|
233
|
-
int glfs_setfsuid (uid_t fsuid) __THROW;
|
234
|
-
int glfs_setfsgid (gid_t fsgid) __THROW;
|
235
|
-
int glfs_setfsgroups (size_t size, const gid_t *list) __THROW;
|
236
|
-
=end
|
237
|
-
attach_function :setfsuid, :glfs_setfsuid, [:int], :int
|
238
|
-
attach_function :setfsgid, :glfs_setfsgid, [:int], :int
|
239
|
-
attach_function :setfsgroups, :glfs_setfsgroups, [:uint, :pointer], :int
|
240
|
-
|
241
|
-
=begin
|
242
|
-
SYNOPSIS
|
243
|
-
|
244
|
-
glfs_open: Open a file.
|
245
|
-
|
246
|
-
DESCRIPTION
|
247
|
-
|
248
|
-
This function opens a file on a virtual mount.
|
249
|
-
|
250
|
-
PARAMETERS
|
251
|
-
|
252
|
-
@fs: The 'virtual mount' object to be initialized.
|
253
|
-
|
254
|
-
@path: Path of the file within the virtual mount.
|
255
|
-
|
256
|
-
@flags: Open flags. See open(2). O_CREAT is not supported.
|
257
|
-
Use glfs_creat() for creating files.
|
258
|
-
|
259
|
-
RETURN VALUES
|
260
|
-
|
261
|
-
NULL : Failure. @errno will be set with the type of failure.
|
262
|
-
Others : Pointer to the opened glfs_fd_t.
|
263
|
-
|
264
|
-
glfs_fd_t *glfs_open (glfs_t *fs, const char *path, int flags) __THROW;
|
265
|
-
=end
|
266
|
-
attach_function :open, :glfs_open, [:pointer, :string, :int], :pointer
|
267
|
-
|
268
|
-
=begin
|
269
|
-
SYNOPSIS
|
270
|
-
|
271
|
-
glfs_creat: Create a file.
|
272
|
-
|
273
|
-
DESCRIPTION
|
274
|
-
|
275
|
-
This function opens a file on a virtual mount.
|
276
|
-
|
277
|
-
PARAMETERS
|
278
|
-
|
279
|
-
@fs: The 'virtual mount' object to be initialized.
|
280
|
-
|
281
|
-
@path: Path of the file within the virtual mount.
|
282
|
-
|
283
|
-
@mode: Permission of the file to be created.
|
284
|
-
|
285
|
-
@flags: Create flags. See open(2). O_EXCL is supported.
|
286
|
-
|
287
|
-
RETURN VALUES
|
288
|
-
|
289
|
-
NULL : Failure. @errno will be set with the type of failure.
|
290
|
-
Others : Pointer to the opened glfs_fd_t.
|
291
|
-
|
292
|
-
glfs_fd_t *glfs_creat (glfs_t *fs, const char *path, int flags,
|
293
|
-
mode_t mode) __THROW;
|
294
|
-
=end
|
295
|
-
attach_function :creat, :glfs_creat, [:pointer, :string, :int, :int], :pointer
|
296
|
-
|
297
|
-
=begin
|
298
|
-
int glfs_close (glfs_fd_t *fd) __THROW;
|
299
|
-
=end
|
300
|
-
attach_function :close, :glfs_close, [:pointer], :int
|
301
|
-
|
302
|
-
=begin
|
303
|
-
// glfs_{read,write}[_async]
|
304
|
-
|
305
|
-
ssize_t glfs_read (glfs_fd_t *fd, void *buf,
|
306
|
-
size_t count, int flags) __THROW;
|
307
|
-
ssize_t glfs_write (glfs_fd_t *fd, const void *buf,
|
308
|
-
size_t count, int flags) __THROW;
|
309
|
-
int glfs_read_async (glfs_fd_t *fd, void *buf, size_t count, int flags,
|
310
|
-
glfs_io_cbk fn, void *data) __THROW;
|
311
|
-
int glfs_write_async (glfs_fd_t *fd, const void *buf, size_t count, int flags,
|
312
|
-
glfs_io_cbk fn, void *data) __THROW;
|
313
|
-
=end
|
314
|
-
attach_function :read, :glfs_read, [:pointer, :pointer, :uint, :int], :uint
|
315
|
-
attach_function :write, :glfs_write, [:pointer, :pointer, :uint, :int], :uint
|
316
|
-
# TODO async
|
317
|
-
|
318
|
-
=begin
|
319
|
-
int glfs_mkdir (glfs_t *fs, const char *path, mode_t mode) __THROW;
|
320
|
-
=end
|
321
|
-
attach_function :mkdir, :glfs_mkdir, [:pointer, :string, :int], :int
|
322
|
-
|
323
|
-
=begin
|
324
|
-
int glfs_unlink (glfs_t *fs, const char *path) __THROW;
|
325
|
-
=end
|
326
|
-
attach_function :unlink, :glfs_unlink, [:pointer, :string], :int
|
327
|
-
|
328
|
-
=begin
|
329
|
-
int glfs_rmdir (glfs_t *fs, const char *path) __THROW;
|
330
|
-
=end
|
331
|
-
attach_function :rmdir, :glfs_rmdir, [:pointer, :string], :int
|
332
|
-
|
333
|
-
=begin
|
334
|
-
int glfs_rename (glfs_t *fs, const char *oldpath, const char *newpath) __THROW;
|
335
|
-
=end
|
336
|
-
attach_function :rename, :glfs_rename, [:pointer, :string, :string], :int
|
337
|
-
|
338
|
-
# TODO the rest
|
339
|
-
|
340
12
|
end
|
@@ -0,0 +1,343 @@
|
|
1
|
+
module GlusterFS
|
2
|
+
extend FFI::Library
|
3
|
+
|
4
|
+
# https://github.com/gluster/glusterfs/blob/master/api/src/glfs.h
|
5
|
+
ffi_lib 'gfapi'
|
6
|
+
|
7
|
+
=begin
|
8
|
+
SYNOPSIS
|
9
|
+
|
10
|
+
glfs_new: Create a new 'virtual mount' object.
|
11
|
+
|
12
|
+
DESCRIPTION
|
13
|
+
|
14
|
+
This is most likely the very first function you will use. This function
|
15
|
+
will create a new glfs_t (virtual mount) object in memory.
|
16
|
+
|
17
|
+
On this newly created glfs_t, you need to be either set a volfile path
|
18
|
+
(glfs_set_volfile) or a volfile server (glfs_set_volfile_server).
|
19
|
+
|
20
|
+
The glfs_t object needs to be initialized with glfs_init() before you
|
21
|
+
can start issuing file operations on it.
|
22
|
+
|
23
|
+
PARAMETERS
|
24
|
+
|
25
|
+
@volname: Name of the volume. This identifies the server-side volume and
|
26
|
+
the fetched volfile (equivalent of --volfile-id command line
|
27
|
+
parameter to glusterfsd). When used with glfs_set_volfile() the
|
28
|
+
@volname has no effect (except for appearing in log messages).
|
29
|
+
|
30
|
+
RETURN VALUES
|
31
|
+
|
32
|
+
NULL : Out of memory condition.
|
33
|
+
Others : Pointer to the newly created glfs_t virtual mount object.
|
34
|
+
|
35
|
+
glfs_t *glfs_new (const char *volname) __THROW;
|
36
|
+
=end
|
37
|
+
attach_function :new, :glfs_new, [:string], :pointer
|
38
|
+
|
39
|
+
=begin
|
40
|
+
SYNOPSIS
|
41
|
+
|
42
|
+
glfs_set_volfile: Specify the path to the volume specification file.
|
43
|
+
|
44
|
+
DESCRIPTION
|
45
|
+
|
46
|
+
If you are using a static volume specification file (without dynamic
|
47
|
+
volume management abilities from the CLI), then specify the path to
|
48
|
+
the volume specification file.
|
49
|
+
|
50
|
+
This is incompatible with glfs_set_volfile_server().
|
51
|
+
|
52
|
+
PARAMETERS
|
53
|
+
|
54
|
+
@fs: The 'virtual mount' object to be configured with the volume
|
55
|
+
specification file.
|
56
|
+
|
57
|
+
@volfile: Path to the locally available volume specification file.
|
58
|
+
|
59
|
+
RETURN VALUES
|
60
|
+
|
61
|
+
0 : Success.
|
62
|
+
-1 : Failure. @errno will be set with the type of failure.
|
63
|
+
|
64
|
+
int glfs_set_volfile (glfs_t *fs, const char *volfile);
|
65
|
+
=end
|
66
|
+
attach_function :set_volfile, :glfs_set_volfile, [:pointer, :string], :int
|
67
|
+
|
68
|
+
=begin
|
69
|
+
SYNOPSIS
|
70
|
+
|
71
|
+
glfs_set_volfile_server: Specify the address of management server.
|
72
|
+
|
73
|
+
DESCRIPTION
|
74
|
+
|
75
|
+
This function specifies the address of the management server (glusterd)
|
76
|
+
to connect, and establish the volume configuration. The @volname
|
77
|
+
parameter passed to glfs_new() is the volume which will be virtually
|
78
|
+
mounted as the glfs_t object. All operations performed by the CLI at
|
79
|
+
the management server will automatically be reflected in the 'virtual
|
80
|
+
mount' object as it maintains a connection to glusterd and polls on
|
81
|
+
configuration change notifications.
|
82
|
+
|
83
|
+
This is incompatible with glfs_set_volfile().
|
84
|
+
|
85
|
+
PARAMETERS
|
86
|
+
|
87
|
+
@fs: The 'virtual mount' object to be configured with the volume
|
88
|
+
specification file.
|
89
|
+
|
90
|
+
@transport: String specifying the transport used to connect to the
|
91
|
+
management daemon. Specifying NULL will result in the usage
|
92
|
+
of the default (tcp) transport type. Permitted values
|
93
|
+
are those what you specify as transport-type in a volume
|
94
|
+
specification file (e.g "tcp", "rdma", "unix".)
|
95
|
+
|
96
|
+
@host: String specifying the address of where to find the management
|
97
|
+
daemon. Depending on the transport type this would either be
|
98
|
+
an FQDN (e.g: "storage01.company.com"), ASCII encoded IP
|
99
|
+
address "192.168.22.1", or a UNIX domain socket path (e.g
|
100
|
+
"/tmp/glusterd.socket".)
|
101
|
+
|
102
|
+
@port: The TCP port number where gluster management daemon is listening.
|
103
|
+
Specifying 0 uses the default port number GF_DEFAULT_BASE_PORT.
|
104
|
+
This parameter is unused if you are using a UNIX domain socket.
|
105
|
+
|
106
|
+
RETURN VALUES
|
107
|
+
|
108
|
+
0 : Success.
|
109
|
+
-1 : Failure. @errno will be set with the type of failure.
|
110
|
+
|
111
|
+
int glfs_set_volfile_server (glfs_t *fs, const char *transport,
|
112
|
+
const char *host, int port) __THROW;
|
113
|
+
=end
|
114
|
+
attach_function :set_volfile_server, :glfs_set_volfile_server,
|
115
|
+
[:pointer, :string, :string, :int], :int
|
116
|
+
|
117
|
+
=begin
|
118
|
+
SYNOPSIS
|
119
|
+
|
120
|
+
glfs_set_logging: Specify logging parameters.
|
121
|
+
|
122
|
+
DESCRIPTION
|
123
|
+
|
124
|
+
This function specifies logging parameters for the virtual mount.
|
125
|
+
Default log file is /dev/null.
|
126
|
+
|
127
|
+
PARAMETERS
|
128
|
+
|
129
|
+
@fs: The 'virtual mount' object to be configured with the logging parameters.
|
130
|
+
|
131
|
+
@logfile: The logfile to be used for logging. Will be created if it does not
|
132
|
+
already exist (provided system permissions allow). If NULL, a new
|
133
|
+
logfile will be created in default log directory associated with
|
134
|
+
the glusterfs installation.
|
135
|
+
|
136
|
+
@loglevel: Numerical value specifying the degree of verbosity. Higher the
|
137
|
+
value, more verbose the logging.
|
138
|
+
|
139
|
+
RETURN VALUES
|
140
|
+
|
141
|
+
0 : Success.
|
142
|
+
-1 : Failure. @errno will be set with the type of failure.
|
143
|
+
|
144
|
+
int glfs_set_logging (glfs_t *fs, const char *logfile, int loglevel) __THROW;
|
145
|
+
=end
|
146
|
+
attach_function :set_logging, :glfs_set_logging, [:pointer, :string, :int], :int
|
147
|
+
|
148
|
+
=begin
|
149
|
+
SYNOPSIS
|
150
|
+
|
151
|
+
glfs_init: Initialize the 'virtual mount'
|
152
|
+
|
153
|
+
DESCRIPTION
|
154
|
+
|
155
|
+
This function initializes the glfs_t object. This consists of many steps:
|
156
|
+
- Spawn a poll-loop thread.
|
157
|
+
- Establish connection to management daemon and receive volume specification.
|
158
|
+
- Construct translator graph and initialize graph.
|
159
|
+
- Wait for initialization (connecting to all bricks) to complete.
|
160
|
+
|
161
|
+
PARAMETERS
|
162
|
+
|
163
|
+
@fs: The 'virtual mount' object to be initialized.
|
164
|
+
|
165
|
+
RETURN VALUES
|
166
|
+
|
167
|
+
0 : Success.
|
168
|
+
-1 : Failure. @errno will be set with the type of failure.
|
169
|
+
|
170
|
+
int glfs_init (glfs_t *fs) __THROW;
|
171
|
+
=end
|
172
|
+
attach_function :init, :glfs_init, [:pointer], :int
|
173
|
+
|
174
|
+
=begin
|
175
|
+
SYNOPSIS
|
176
|
+
|
177
|
+
glfs_fini: Cleanup and destroy the 'virtual mount'
|
178
|
+
|
179
|
+
DESCRIPTION
|
180
|
+
|
181
|
+
This function attempts to gracefully destroy glfs_t object. An attempt is
|
182
|
+
made to wait for all background processing to complete before returning.
|
183
|
+
|
184
|
+
glfs_fini() must be called after all operations on glfs_t is finished.
|
185
|
+
|
186
|
+
IMPORTANT
|
187
|
+
|
188
|
+
IT IS NECESSARY TO CALL glfs_fini() ON ALL THE INITIALIZED glfs_t
|
189
|
+
OBJECTS BEFORE TERMINATING THE PROGRAM. THERE MAY BE CACHED AND
|
190
|
+
UNWRITTEN / INCOMPLETE OPERATIONS STILL IN PROGRESS EVEN THOUGH THE
|
191
|
+
API CALLS HAVE RETURNED. glfs_fini() WILL WAIT FOR BACKGROUND OPERATIONS
|
192
|
+
TO COMPLETE BEFORE RETURNING, THEREBY MAKING IT SAFE FOR THE PROGRAM TO
|
193
|
+
EXIT.
|
194
|
+
|
195
|
+
PARAMETERS
|
196
|
+
|
197
|
+
@fs: The 'virtual mount' object to be destroyed.
|
198
|
+
|
199
|
+
RETURN VALUES
|
200
|
+
|
201
|
+
0 : Success.
|
202
|
+
|
203
|
+
int glfs_fini (glfs_t *fs) __THROW;
|
204
|
+
=end
|
205
|
+
attach_function :fini, :glfs_fini, [:pointer], :int
|
206
|
+
|
207
|
+
=begin
|
208
|
+
PER THREAD IDENTITY MODIFIERS
|
209
|
+
|
210
|
+
The following operations enable to set a per thread identity context
|
211
|
+
for the glfs APIs to perform operations as. The calls here are kept as close
|
212
|
+
to POSIX equivalents as possible.
|
213
|
+
|
214
|
+
NOTES:
|
215
|
+
|
216
|
+
- setgroups is a per thread setting, hence this is named as fsgroups to be
|
217
|
+
close in naming to the fs(u/g)id APIs
|
218
|
+
- Typical mode of operation is to set the IDs as required, with the
|
219
|
+
supplementary groups being optionally set, make the glfs call and post the
|
220
|
+
glfs operation set them back to eu/gid or uid/gid as appropriate to the
|
221
|
+
caller
|
222
|
+
- The groups once set, need to be unset by setting the size to 0 (in which
|
223
|
+
case the list argument is a do not care)
|
224
|
+
- Once a process for a thread of operation choses to set the IDs, all glfs
|
225
|
+
calls made from that thread would default to the IDs set for the thread.
|
226
|
+
As a result use these APIs with care and ensure that the set IDs are
|
227
|
+
reverted to global process defaults as required.
|
228
|
+
|
229
|
+
int glfs_setfsuid (uid_t fsuid) __THROW;
|
230
|
+
int glfs_setfsgid (gid_t fsgid) __THROW;
|
231
|
+
int glfs_setfsgroups (size_t size, const gid_t *list) __THROW;
|
232
|
+
=end
|
233
|
+
attach_function :setfsuid, :glfs_setfsuid, [:int], :int
|
234
|
+
attach_function :setfsgid, :glfs_setfsgid, [:int], :int
|
235
|
+
attach_function :setfsgroups, :glfs_setfsgroups, [:uint, :pointer], :int
|
236
|
+
|
237
|
+
=begin
|
238
|
+
SYNOPSIS
|
239
|
+
|
240
|
+
glfs_open: Open a file.
|
241
|
+
|
242
|
+
DESCRIPTION
|
243
|
+
|
244
|
+
This function opens a file on a virtual mount.
|
245
|
+
|
246
|
+
PARAMETERS
|
247
|
+
|
248
|
+
@fs: The 'virtual mount' object to be initialized.
|
249
|
+
|
250
|
+
@path: Path of the file within the virtual mount.
|
251
|
+
|
252
|
+
@flags: Open flags. See open(2). O_CREAT is not supported.
|
253
|
+
Use glfs_creat() for creating files.
|
254
|
+
|
255
|
+
RETURN VALUES
|
256
|
+
|
257
|
+
NULL : Failure. @errno will be set with the type of failure.
|
258
|
+
Others : Pointer to the opened glfs_fd_t.
|
259
|
+
|
260
|
+
glfs_fd_t *glfs_open (glfs_t *fs, const char *path, int flags) __THROW;
|
261
|
+
=end
|
262
|
+
attach_function :open, :glfs_open, [:pointer, :string, :int], :pointer
|
263
|
+
|
264
|
+
=begin
|
265
|
+
SYNOPSIS
|
266
|
+
|
267
|
+
glfs_creat: Create a file.
|
268
|
+
|
269
|
+
DESCRIPTION
|
270
|
+
|
271
|
+
This function opens a file on a virtual mount.
|
272
|
+
|
273
|
+
PARAMETERS
|
274
|
+
|
275
|
+
@fs: The 'virtual mount' object to be initialized.
|
276
|
+
|
277
|
+
@path: Path of the file within the virtual mount.
|
278
|
+
|
279
|
+
@mode: Permission of the file to be created.
|
280
|
+
|
281
|
+
@flags: Create flags. See open(2). O_EXCL is supported.
|
282
|
+
|
283
|
+
RETURN VALUES
|
284
|
+
|
285
|
+
NULL : Failure. @errno will be set with the type of failure.
|
286
|
+
Others : Pointer to the opened glfs_fd_t.
|
287
|
+
|
288
|
+
glfs_fd_t *glfs_creat (glfs_t *fs, const char *path, int flags,
|
289
|
+
mode_t mode) __THROW;
|
290
|
+
=end
|
291
|
+
attach_function :creat, :glfs_creat, [:pointer, :string, :int, :int], :pointer
|
292
|
+
|
293
|
+
=begin
|
294
|
+
int glfs_close (glfs_fd_t *fd) __THROW;
|
295
|
+
=end
|
296
|
+
attach_function :close, :glfs_close, [:pointer], :int
|
297
|
+
|
298
|
+
=begin
|
299
|
+
// glfs_{read,write}[_async]
|
300
|
+
|
301
|
+
ssize_t glfs_read (glfs_fd_t *fd, void *buf,
|
302
|
+
size_t count, int flags) __THROW;
|
303
|
+
ssize_t glfs_write (glfs_fd_t *fd, const void *buf,
|
304
|
+
size_t count, int flags) __THROW;
|
305
|
+
int glfs_read_async (glfs_fd_t *fd, void *buf, size_t count, int flags,
|
306
|
+
glfs_io_cbk fn, void *data) __THROW;
|
307
|
+
int glfs_write_async (glfs_fd_t *fd, const void *buf, size_t count, int flags,
|
308
|
+
glfs_io_cbk fn, void *data) __THROW;
|
309
|
+
=end
|
310
|
+
attach_function :read, :glfs_read, [:pointer, :pointer, :uint, :int], :uint
|
311
|
+
attach_function :write, :glfs_write, [:pointer, :pointer, :uint, :int], :uint
|
312
|
+
# TODO async
|
313
|
+
|
314
|
+
=begin
|
315
|
+
int glfs_mkdir (glfs_t *fs, const char *path, mode_t mode) __THROW;
|
316
|
+
=end
|
317
|
+
attach_function :mkdir, :glfs_mkdir, [:pointer, :string, :int], :int
|
318
|
+
|
319
|
+
=begin
|
320
|
+
int glfs_unlink (glfs_t *fs, const char *path) __THROW;
|
321
|
+
=end
|
322
|
+
attach_function :unlink, :glfs_unlink, [:pointer, :string], :int
|
323
|
+
|
324
|
+
=begin
|
325
|
+
int glfs_rmdir (glfs_t *fs, const char *path) __THROW;
|
326
|
+
=end
|
327
|
+
attach_function :rmdir, :glfs_rmdir, [:pointer, :string], :int
|
328
|
+
|
329
|
+
=begin
|
330
|
+
int glfs_rename (glfs_t *fs, const char *oldpath, const char *newpath) __THROW;
|
331
|
+
=end
|
332
|
+
attach_function :rename, :glfs_rename, [:pointer, :string, :string], :int
|
333
|
+
|
334
|
+
=begin
|
335
|
+
int glfs_lstat (glfs_t *fs, const char *path, struct stat *buf) __THROW;
|
336
|
+
int glfs_stat (glfs_t *fs, const char *path, struct stat *buf) __THROW;
|
337
|
+
int glfs_fstat (glfs_fd_t *fd, struct stat *buf) __THROW;
|
338
|
+
=end
|
339
|
+
attach_function :lstat, :glfs_lstat, [:pointer, :string, :pointer], :int
|
340
|
+
|
341
|
+
# TODO the rest
|
342
|
+
|
343
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class GlusterFS::Client
|
2
|
+
class << self
|
3
|
+
def mount(volume_name, host, port = 24007, protocol = 'tcp')
|
4
|
+
volume = GlusterFS::Volume.new(volume_name)
|
5
|
+
volume.mount(host, port, protocol)
|
6
|
+
volume
|
7
|
+
end
|
8
|
+
|
9
|
+
def unmount(volume)
|
10
|
+
GlusterFS.fini(volume.fs)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/glusterfs/file.rb
CHANGED
@@ -1,25 +1,70 @@
|
|
1
1
|
require "tempfile"
|
2
2
|
class GlusterFS::File
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
attr_reader :volume, :path
|
4
|
+
def initialize(volume, path)
|
5
|
+
@volume = volume
|
6
|
+
@path = path
|
7
|
+
end
|
8
|
+
|
9
|
+
def read_file(buf_size = 4092)
|
10
|
+
raise GlusterFS::Error, "File is empty or does not exist: #{@path}" if lstat[:st_size] < 1
|
11
|
+
fd = GlusterFS.open(@volume.fs, @path, 0)
|
12
|
+
temp = Tempfile.new(path.gsub('/', '-'))
|
13
|
+
buff = FFI::MemoryPointer.new(:char, buf_size)
|
14
|
+
res = 1
|
15
|
+
while res > 0
|
16
|
+
res = GlusterFS.read(fd, buff, buf_size, 0)
|
17
|
+
temp.write(buff.get_bytes(0, res)) if res > 0
|
16
18
|
end
|
19
|
+
GlusterFS.close(fd)
|
20
|
+
temp.rewind
|
21
|
+
temp
|
22
|
+
end
|
17
23
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
def read(buf_size = 4092)
|
25
|
+
fd = GlusterFS.open(@volume.fs, @path, 0)
|
26
|
+
temp = ''
|
27
|
+
buff = FFI::MemoryPointer.new(:char, buf_size)
|
28
|
+
res = 1
|
29
|
+
lstat
|
30
|
+
while res > 0
|
31
|
+
res = GlusterFS.read(fd, buff, buf_size, 0)
|
32
|
+
temp << buff.get_bytes(0, res) if res > 0
|
23
33
|
end
|
34
|
+
GlusterFS.close(fd)
|
35
|
+
temp
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_file(file, perms = 0644)
|
39
|
+
fd = GlusterFS.creat(@volume.fs, path, 2, perms)
|
40
|
+
res = GlusterFS.write(fd, file.read, file.size, 0)
|
41
|
+
GlusterFS.close(fd)
|
42
|
+
res
|
43
|
+
end
|
44
|
+
|
45
|
+
def write(data, perms = 0644)
|
46
|
+
fd = GlusterFS.creat(@volume.fs, path, 2, perms)
|
47
|
+
res = GlusterFS.write(fd, data, data.size, 0)
|
48
|
+
GlusterFS.close(fd)
|
49
|
+
res
|
50
|
+
end
|
51
|
+
|
52
|
+
def unlink
|
53
|
+
GlusterFS.unlink(@volume.fs, @path)
|
54
|
+
end
|
55
|
+
|
56
|
+
def lstat
|
57
|
+
data = GlusterFS::Stat.new
|
58
|
+
GlusterFS.lstat(@volume.fs, @path, data)
|
59
|
+
data
|
60
|
+
end
|
61
|
+
|
62
|
+
def exists?
|
63
|
+
lstat[:st_blocks] > 0
|
64
|
+
end
|
65
|
+
|
66
|
+
def size
|
67
|
+
lstat[:st_size]
|
24
68
|
end
|
69
|
+
|
25
70
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class GlusterFS::Stat < FFI::Struct
|
2
|
+
layout :st_dev, :dev_t,
|
3
|
+
:st_ino, :ino_t,
|
4
|
+
:st_nlink, :nlink_t,
|
5
|
+
:st_mode, :mode_t,
|
6
|
+
:st_uid, :uid_t,
|
7
|
+
:st_gid, :gid_t,
|
8
|
+
:st_rdev, :dev_t,
|
9
|
+
:st_size, :ulong,
|
10
|
+
:st_blksize, :ulong,
|
11
|
+
:st_blocks, :quad_t,
|
12
|
+
:st_atime, :ulong,
|
13
|
+
:st_atimesec, :ulong,
|
14
|
+
:st_mtime, :ulong,
|
15
|
+
:st_mtimesec, :ulong,
|
16
|
+
:st_ctime, :ulong,
|
17
|
+
:st_ctimesec, :ulong
|
18
|
+
end
|
data/lib/glusterfs/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
class GlusterFS::Volume
|
2
|
+
attr_reader :name, :fs, :mounted
|
3
|
+
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
@fs = GlusterFS.new(@name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def mount(host, port = 24007, protocol = 'tcp')
|
10
|
+
GlusterFS.set_volfile_server(@fs, protocol, host, port)
|
11
|
+
result = GlusterFS.init(@fs)
|
12
|
+
if result != 0
|
13
|
+
raise GlusterFS::Error,
|
14
|
+
"Failed to mount volume '#{volume_name}' on #{protocol}://#{host}:#{port}"
|
15
|
+
end
|
16
|
+
@mounted = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def mounted?
|
20
|
+
@mounted
|
21
|
+
end
|
22
|
+
|
23
|
+
def unmount
|
24
|
+
if mounted?
|
25
|
+
GlusterFS.fini(@fs)
|
26
|
+
@mounted = false
|
27
|
+
true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/libgfapi-ruby.gemspec
CHANGED
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module GlusterFS
|
4
|
+
describe File do
|
5
|
+
let(:volume) { Client.mount(GFS_VOLUME, GFS_SERVER_HOST) }
|
6
|
+
let(:file_name) { "test-#{Time.now.to_i}" }
|
7
|
+
let(:file) { File.new(volume, file_name) }
|
8
|
+
let(:data) { '123' }
|
9
|
+
|
10
|
+
after do
|
11
|
+
file.unlink
|
12
|
+
volume.unmount
|
13
|
+
end
|
14
|
+
|
15
|
+
context '#read' do
|
16
|
+
before { file.write(data) }
|
17
|
+
subject { file.read }
|
18
|
+
it { should == data }
|
19
|
+
end
|
20
|
+
|
21
|
+
context '#read_file' do
|
22
|
+
before { file.write(data) }
|
23
|
+
let(:result) { file.read_file }
|
24
|
+
specify 'result is correctly formed tempfile' do
|
25
|
+
result.should be_a Tempfile
|
26
|
+
result.read.should == data
|
27
|
+
result.close
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context '#write' do
|
32
|
+
context 'writes file' do
|
33
|
+
subject { file.write(data) }
|
34
|
+
it('returns bytes written') { should == data.length }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'overwrites file' do
|
38
|
+
let(:file2) { File.new(volume, file_name) }
|
39
|
+
let(:data2) { '1234' }
|
40
|
+
|
41
|
+
before { file.write(data) }
|
42
|
+
after { file2.unlink }
|
43
|
+
|
44
|
+
subject { file2.write(data2) }
|
45
|
+
it('returns bytes written') { should == data2.length }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context '#write_file' do
|
50
|
+
let(:data) do
|
51
|
+
d = Tempfile.new('test')
|
52
|
+
d.write '12345'
|
53
|
+
d.rewind
|
54
|
+
d
|
55
|
+
end
|
56
|
+
after { data.close }
|
57
|
+
|
58
|
+
context 'writes file' do
|
59
|
+
subject { file.write_file(data) }
|
60
|
+
it('returns bytes written') { should == data.length }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'overwrites file' do
|
64
|
+
let(:file2) { File.new(volume, file_name) }
|
65
|
+
let(:data2) do
|
66
|
+
d = Tempfile.new('test2')
|
67
|
+
d.write '7890'
|
68
|
+
d.rewind
|
69
|
+
d
|
70
|
+
end
|
71
|
+
|
72
|
+
before { file.write_file(data) }
|
73
|
+
after do
|
74
|
+
file2.unlink
|
75
|
+
data2.close
|
76
|
+
end
|
77
|
+
|
78
|
+
subject { file2.write_file(data2) }
|
79
|
+
it('returns bytes written') { should == data2.length }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context '#unlink' do
|
84
|
+
before do
|
85
|
+
file.write(data)
|
86
|
+
file.unlink
|
87
|
+
end
|
88
|
+
subject { file.exists? }
|
89
|
+
it('deletes the file') { should_not be_true }
|
90
|
+
end
|
91
|
+
|
92
|
+
context '#exist?' do
|
93
|
+
context 'on existing file' do
|
94
|
+
before { file.write(data) }
|
95
|
+
subject { file.exists? }
|
96
|
+
it { should be_true }
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'on non-existing file' do
|
100
|
+
subject { file.exists? }
|
101
|
+
it { should_not be_true }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context '#lstat' do
|
106
|
+
context 'on existing file' do
|
107
|
+
before { file.write(data) }
|
108
|
+
let(:lstat) { file.lstat }
|
109
|
+
specify 'lstat response is as expected' do
|
110
|
+
lstat[:st_dev].should_not == 0
|
111
|
+
lstat[:st_ino].should_not == 0
|
112
|
+
lstat[:st_nlink].should_not == 0
|
113
|
+
lstat[:st_mode].should_not == 0
|
114
|
+
lstat[:st_uid].should == 0
|
115
|
+
lstat[:st_gid].should == 0
|
116
|
+
lstat[:st_rdev].should == 0
|
117
|
+
lstat[:st_size].should == data.size
|
118
|
+
lstat[:st_blksize].should_not == 0
|
119
|
+
lstat[:st_blocks].should == 1
|
120
|
+
lstat[:st_atime].should_not == 0
|
121
|
+
lstat[:st_mtime].should_not == 0
|
122
|
+
lstat[:st_ctime].should_not == 0
|
123
|
+
lstat[:st_atimesec].should_not == 0
|
124
|
+
lstat[:st_mtimesec].should_not == 0
|
125
|
+
lstat[:st_ctimesec].should_not == 0
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'on non-existing file' do
|
130
|
+
let(:lstat) { file.lstat }
|
131
|
+
specify 'lstat response is as expected' do
|
132
|
+
lstat[:st_dev].should == 0
|
133
|
+
lstat[:st_ino].should == 0
|
134
|
+
lstat[:st_nlink].should == 0
|
135
|
+
lstat[:st_mode].should == 0
|
136
|
+
lstat[:st_uid].should == 0
|
137
|
+
lstat[:st_gid].should == 0
|
138
|
+
lstat[:st_rdev].should == 0
|
139
|
+
lstat[:st_size].should == 0
|
140
|
+
lstat[:st_blksize].should == 0
|
141
|
+
lstat[:st_blocks].should == 0
|
142
|
+
lstat[:st_atime].should == 0
|
143
|
+
lstat[:st_mtime].should == 0
|
144
|
+
lstat[:st_ctime].should == 0
|
145
|
+
lstat[:st_atimesec].should == 0
|
146
|
+
lstat[:st_mtimesec].should == 0
|
147
|
+
lstat[:st_ctimesec].should == 0
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'glusterfs'
|
3
|
+
require 'pry'
|
4
|
+
require 'pry-nav'
|
5
|
+
|
6
|
+
GFS_SERVER_HOST = '127.0.0.1'
|
7
|
+
GFS_SERVER_PORT = 24007
|
8
|
+
GFS_VOLUME = 'dist-volume'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.color_enabled = true
|
12
|
+
config.formatter = 'documentation'
|
13
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas Varaneckas
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-nav
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: Ruby bindings for libgfapi (GlusterFS API)
|
56
84
|
email:
|
57
85
|
- tomas.varaneckas@gmail.com
|
@@ -65,9 +93,18 @@ files:
|
|
65
93
|
- README.md
|
66
94
|
- Rakefile
|
67
95
|
- lib/glusterfs.rb
|
96
|
+
- lib/glusterfs/bindings.rb
|
97
|
+
- lib/glusterfs/client.rb
|
98
|
+
- lib/glusterfs/directory.rb
|
99
|
+
- lib/glusterfs/error.rb
|
68
100
|
- lib/glusterfs/file.rb
|
101
|
+
- lib/glusterfs/stat.rb
|
69
102
|
- lib/glusterfs/version.rb
|
103
|
+
- lib/glusterfs/volume.rb
|
70
104
|
- libgfapi-ruby.gemspec
|
105
|
+
- spec/glusterfs/client_spec.rb
|
106
|
+
- spec/glusterfs/file_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
71
108
|
homepage: https://github.com/spajus/libgfapi-ruby
|
72
109
|
licenses:
|
73
110
|
- MIT
|
@@ -92,5 +129,8 @@ rubygems_version: 2.0.6
|
|
92
129
|
signing_key:
|
93
130
|
specification_version: 4
|
94
131
|
summary: Ruby bindings for libgfapi (GlusterFS API)
|
95
|
-
test_files:
|
132
|
+
test_files:
|
133
|
+
- spec/glusterfs/client_spec.rb
|
134
|
+
- spec/glusterfs/file_spec.rb
|
135
|
+
- spec/spec_helper.rb
|
96
136
|
has_rdoc:
|