libgfapi-ruby 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0669cfea34e893de481678cc8e1b9a67e795cbf4
4
- data.tar.gz: 1b71461efff897518ebcfa0dc06c7e3c2f9c3e29
3
+ metadata.gz: 218fc8b79c32f5db3573e1714cba7376906d2328
4
+ data.tar.gz: fa6b48a3b70348aa703cc68cbee7a2802ae52f92
5
5
  SHA512:
6
- metadata.gz: ba03a9428231f95351eb74732df8c33240453bc59a3a051aadae9f5d9c074ce5ecb698fcc7bc55a280de11498aaa810b959fb72e9e322d139d1ede07057f4921
7
- data.tar.gz: 04db7ce3f2046076f6af679d02eea68f17a0da9ac086031321fe6c0aa97dc81f72f0524fb0f1952ebec100d7f6da6cecf12a34a9b6e151584de700b6d100d323
6
+ metadata.gz: 7804714a56eaf5364e9fb24cfd86d3f278ef92ef835b3356a60e29572d88b18d2257b37cb8387a023f27ae4cdc3135afe2991bf83d5069810c9757aaad550b90
7
+ data.tar.gz: 0c31210229bc5b178e2a586507f49da15e6616eee3496ecfe2d61370aae72c60f07795052fd2e689db4b60dc21a43f5ad915c9ea3592e7a0802aaf980bae935f
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ Vagrantfile
19
+ .vagrant
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
- fs = GlusterFS.new 'my_volume'
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 fs, '/some_dir', 0755
32
+ # Make a new directory (raw)
33
+ GlusterFS.mkdir(volume.fs, '/some_dir', 0755)
32
34
 
33
35
  # Write a file
34
- file = File.open('/some/file')
35
- size = GlusterFS::File.write(fs, '/gfs/file/path', file)
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.read(fs, '/gfs/file/path')
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
- # Destroy virtual mount
43
- GlusterFS.fini fs
49
+ # Unmount virtual mount
50
+ volume.unmount
44
51
  ```
45
52
 
46
53
  ## Contributing
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new("spec")
5
+
6
+ task default: :spec
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 "ffi"
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
@@ -0,0 +1,2 @@
1
+ class GlusterFS::Directory
2
+ end
@@ -0,0 +1,2 @@
1
+ class GlusterFS::Error < StandardError
2
+ end
@@ -1,25 +1,70 @@
1
1
  require "tempfile"
2
2
  class GlusterFS::File
3
- class << self
4
- def read(fs, path, buf_size = 4092)
5
- fd = GlusterFS.open(fs, path, 0)
6
- temp = Tempfile.new(path.gsub('/', '-'))
7
- buff = FFI::MemoryPointer.new(:char, buf_size)
8
- res = 1
9
- while res > 0
10
- res = GlusterFS.read(fd, buff, buf_size, 0)
11
- temp.write(buff.get_bytes(0, res)) if res > 0
12
- end
13
- GlusterFS.close(fd)
14
- temp.rewind
15
- temp
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
- def write(fs, path, file, perms = 0644)
19
- fd = GlusterFS.creat(fs, path, 2, perms)
20
- res = GlusterFS.write(fd, file.read, file.size, 0)
21
- GlusterFS.close(fd)
22
- res
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
@@ -1,3 +1,3 @@
1
1
  module GlusterFS
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -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
@@ -21,4 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "ffi", "~> 1.9"
22
22
  spec.add_development_dependency "bundler", "~> 1.5"
23
23
  spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "pry-nav"
25
+ spec.add_development_dependency "rspec"
24
26
  end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ module GlusterFS
4
+ describe GlusterFS::Client do
5
+ it 'mounts volume' do
6
+ volume = GlusterFS::Client.mount(GFS_VOLUME, GFS_SERVER_HOST)
7
+ volume.name.should == GFS_VOLUME
8
+ end
9
+ end
10
+ end
@@ -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
@@ -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.3
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: