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 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: