ruby-libvirt-catphish 0.7.1

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.
@@ -0,0 +1,6 @@
1
+ #ifndef STORAGE_H
2
+ #define STORAGE_H
3
+
4
+ void ruby_libvirt_storage_init(void);
5
+
6
+ #endif
@@ -0,0 +1,392 @@
1
+ /*
2
+ * stream.c: virStream methods
3
+ *
4
+ * Copyright (C) 2007,2010 Red Hat Inc.
5
+ * Copyright (C) 2013-2016 Chris Lalancette <clalancette@gmail.com>
6
+ *
7
+ * This library is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * This library is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with this library; if not, write to the Free Software
19
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ */
21
+
22
+ #include <ruby.h>
23
+ #include <libvirt/libvirt.h>
24
+ #include <libvirt/virterror.h>
25
+ #include "common.h"
26
+ #include "connect.h"
27
+ #include "extconf.h"
28
+
29
+ #if HAVE_TYPE_VIRSTREAMPTR
30
+ static VALUE c_stream;
31
+
32
+ static void stream_free(void *s)
33
+ {
34
+ ruby_libvirt_free_struct(Stream, s);
35
+ }
36
+
37
+ virStreamPtr ruby_libvirt_stream_get(VALUE s)
38
+ {
39
+ ruby_libvirt_get_struct(Stream, s);
40
+ }
41
+
42
+ VALUE ruby_libvirt_stream_new(virStreamPtr s, VALUE conn)
43
+ {
44
+ return ruby_libvirt_new_class(c_stream, s, conn, stream_free);
45
+ }
46
+
47
+ /*
48
+ * call-seq:
49
+ * stream.send(buffer) -> Fixnum
50
+ *
51
+ * Call virStreamSend[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamSend]
52
+ * to send the data in buffer out to the stream. The return value is the
53
+ * number of bytes sent, which may be less than the size of the buffer. If
54
+ * an error occurred, -1 is returned. If the transmit buffers are full and the
55
+ * stream is marked non-blocking, returns -2.
56
+ */
57
+ static VALUE libvirt_stream_send(VALUE s, VALUE buffer)
58
+ {
59
+ int ret;
60
+
61
+ StringValue(buffer);
62
+
63
+ ret = virStreamSend(ruby_libvirt_stream_get(s), RSTRING_PTR(buffer),
64
+ RSTRING_LEN(buffer));
65
+ ruby_libvirt_raise_error_if(ret == -1, e_RetrieveError, "virStreamSend",
66
+ ruby_libvirt_connect_get(s));
67
+
68
+ return INT2NUM(ret);
69
+ }
70
+
71
+ /*
72
+ * call-seq:
73
+ * stream.recv(bytes) -> [return_value, data]
74
+ *
75
+ * Call virStreamRecv[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamRecv]
76
+ * to receive up to bytes amount of data from the stream. The return is an
77
+ * array with two elements; the return code from the virStreamRecv call and
78
+ * the data (as a String) read from the stream. If an error occurred, the
79
+ * return_value is set to -1. If there is no data pending and the stream is
80
+ * marked as non-blocking, return_value is set to -2.
81
+ */
82
+ static VALUE libvirt_stream_recv(VALUE s, VALUE bytes)
83
+ {
84
+ char *data;
85
+ int ret;
86
+ VALUE result;
87
+
88
+ data = alloca(sizeof(char) * NUM2INT(bytes));
89
+
90
+ ret = virStreamRecv(ruby_libvirt_stream_get(s), data, NUM2INT(bytes));
91
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError, "virStreamRecv",
92
+ ruby_libvirt_connect_get(s));
93
+
94
+ result = rb_ary_new2(2);
95
+
96
+ rb_ary_store(result, 0, INT2NUM(ret));
97
+ rb_ary_store(result, 1, rb_str_new(data, ret));
98
+
99
+ return result;
100
+ }
101
+
102
+ static int internal_sendall(virStreamPtr RUBY_LIBVIRT_UNUSED(st), char *data,
103
+ size_t nbytes, void *opaque)
104
+ {
105
+ VALUE result, retcode, buffer;
106
+
107
+ result = rb_yield_values(2, (VALUE)opaque, INT2NUM(nbytes));
108
+
109
+ if (TYPE(result) != T_ARRAY) {
110
+ rb_raise(rb_eTypeError, "wrong type (expected Array)");
111
+ }
112
+
113
+ if (RARRAY_LEN(result) != 2) {
114
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for 2)",
115
+ RARRAY_LEN(result));
116
+ }
117
+
118
+ retcode = rb_ary_entry(result, 0);
119
+ buffer = rb_ary_entry(result, 1);
120
+
121
+ if (NUM2INT(retcode) < 0) {
122
+ return NUM2INT(retcode);
123
+ }
124
+
125
+ StringValue(buffer);
126
+
127
+ if (RSTRING_LEN(buffer) > (int)nbytes) {
128
+ rb_raise(rb_eArgError, "asked for %zd bytes, block returned %ld",
129
+ nbytes, RSTRING_LEN(buffer));
130
+ }
131
+
132
+ memcpy(data, RSTRING_PTR(buffer), RSTRING_LEN(buffer));
133
+
134
+ return RSTRING_LEN(buffer);
135
+ }
136
+
137
+ /*
138
+ * call-seq:
139
+ * stream.sendall(opaque=nil){|opaque, nbytes| send block} -> nil
140
+ *
141
+ * Call virStreamSendAll[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamSendAll]
142
+ * to send the entire data stream. The send block is required and is executed
143
+ * one or more times to send data. Each invocation of the send block yields
144
+ * the opaque data passed into the initial call and the number of bytes this
145
+ * iteration is prepared to handle. The send block should return an array of
146
+ * 2 elements; the first element should be the return code from the block
147
+ * (-1 for error, 0 otherwise), and the second element should be the data
148
+ * that the block prepared to send.
149
+ */
150
+ static VALUE libvirt_stream_sendall(int argc, VALUE *argv, VALUE s)
151
+ {
152
+ VALUE opaque = RUBY_Qnil;
153
+ int ret;
154
+
155
+ if (!rb_block_given_p()) {
156
+ rb_raise(rb_eRuntimeError, "A block must be provided");
157
+ }
158
+
159
+ rb_scan_args(argc, argv, "01", &opaque);
160
+
161
+ ret = virStreamSendAll(ruby_libvirt_stream_get(s), internal_sendall,
162
+ (void *)opaque);
163
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError, "virStreamSendAll",
164
+ ruby_libvirt_connect_get(s));
165
+
166
+ return Qnil;
167
+ }
168
+
169
+ static int internal_recvall(virStreamPtr RUBY_LIBVIRT_UNUSED(st),
170
+ const char *buf, size_t nbytes, void *opaque)
171
+ {
172
+ VALUE result;
173
+
174
+ result = rb_yield_values(2, rb_str_new(buf, nbytes), (VALUE)opaque);
175
+
176
+ if (TYPE(result) != T_FIXNUM) {
177
+ rb_raise(rb_eArgError, "wrong type (expected an integer)");
178
+ }
179
+
180
+ return NUM2INT(result);
181
+ }
182
+
183
+ /*
184
+ * call-seq:
185
+ * stream.recvall(opaque){|data, opaque| receive block} -> nil
186
+ *
187
+ * Call virStreamRecvAll[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamRecvAll]
188
+ * to receive the entire data stream. The receive block is required and is
189
+ * called one or more times to receive data. Each invocation of the receive
190
+ * block yields the data received and the opaque data passed into the initial
191
+ * call. The block should return -1 if an error occurred and 0 otherwise.
192
+ */
193
+ static VALUE libvirt_stream_recvall(int argc, VALUE *argv, VALUE s)
194
+ {
195
+ VALUE opaque = RUBY_Qnil;
196
+ int ret;
197
+
198
+ if (!rb_block_given_p()) {
199
+ rb_raise(rb_eRuntimeError, "A block must be provided");
200
+ }
201
+
202
+ rb_scan_args(argc, argv, "01", &opaque);
203
+
204
+ ret = virStreamRecvAll(ruby_libvirt_stream_get(s), internal_recvall,
205
+ (void *)opaque);
206
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError, "virStreamRecvAll",
207
+ ruby_libvirt_connect_get(s));
208
+
209
+ return Qnil;
210
+ }
211
+
212
+ static void stream_event_callback(virStreamPtr st, int events, void *opaque)
213
+ {
214
+ VALUE passthrough = (VALUE)opaque;
215
+ VALUE cb, cb_opaque, news, s;
216
+
217
+ if (TYPE(passthrough) != T_ARRAY) {
218
+ rb_raise(rb_eTypeError,
219
+ "wrong domain event lifecycle callback argument type (expected Array)");
220
+ }
221
+
222
+ if (RARRAY_LEN(passthrough) != 3) {
223
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for 3)",
224
+ RARRAY_LEN(passthrough));
225
+ }
226
+
227
+ cb = rb_ary_entry(passthrough, 0);
228
+ cb_opaque = rb_ary_entry(passthrough, 1);
229
+ s = rb_ary_entry(passthrough, 2);
230
+
231
+ news = ruby_libvirt_stream_new(st, ruby_libvirt_conn_attr(s));
232
+ if (strcmp(rb_obj_classname(cb), "Symbol") == 0) {
233
+ rb_funcall(rb_class_of(cb), rb_to_id(cb), 3, news, INT2NUM(events),
234
+ cb_opaque);
235
+ }
236
+ else if (strcmp(rb_obj_classname(cb), "Proc") == 0) {
237
+ rb_funcall(cb, rb_intern("call"), 3, news, INT2NUM(events), cb_opaque);
238
+ }
239
+ else {
240
+ rb_raise(rb_eTypeError,
241
+ "wrong stream event callback (expected Symbol or Proc)");
242
+ }
243
+ }
244
+
245
+ /*
246
+ * call-seq:
247
+ * stream.event_add_callback(events, callback, opaque=nil) -> nil
248
+ *
249
+ * Call virStreamEventAddCallback[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamEventAddCallback]
250
+ * to register a callback to be notified when a stream becomes readable or
251
+ * writeable. The events parameter is an integer representing the events the
252
+ * user is interested in; it should be one or more of EVENT_READABLE,
253
+ * EVENT_WRITABLE, EVENT_ERROR, and EVENT_HANGUP, ORed together. The callback
254
+ * can either be a Symbol (that is the name of a method to callback) or a Proc.
255
+ * The callback should accept 3 parameters: a pointer to the Stream object
256
+ * itself, the integer that represents the events that actually occurred, and
257
+ * an opaque pointer that was (optionally) passed into
258
+ * stream.event_add_callback to begin with.
259
+ */
260
+ static VALUE libvirt_stream_event_add_callback(int argc, VALUE *argv, VALUE s)
261
+ {
262
+ VALUE events = RUBY_Qnil, callback = RUBY_Qnil, opaque = RUBY_Qnil, passthrough;
263
+ int ret;
264
+
265
+ rb_scan_args(argc, argv, "21", &events, &callback, &opaque);
266
+
267
+ if (!ruby_libvirt_is_symbol_or_proc(callback)) {
268
+ rb_raise(rb_eTypeError,
269
+ "wrong argument type (expected Symbol or Proc)");
270
+ }
271
+
272
+ passthrough = rb_ary_new2(3);
273
+ rb_ary_store(passthrough, 0, callback);
274
+ rb_ary_store(passthrough, 1, opaque);
275
+ rb_ary_store(passthrough, 2, s);
276
+
277
+ ret = virStreamEventAddCallback(ruby_libvirt_stream_get(s), NUM2INT(events),
278
+ stream_event_callback, (void *)passthrough,
279
+ NULL);
280
+ ruby_libvirt_raise_error_if(ret < 0, e_RetrieveError,
281
+ "virStreamEventAddCallback",
282
+ ruby_libvirt_connect_get(s));
283
+
284
+ return Qnil;
285
+ }
286
+
287
+ /*
288
+ * call-seq:
289
+ * stream.event_update_callback(events) -> nil
290
+ *
291
+ * Call virStreamEventUpdateCallback[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamEventUpdateCallback]
292
+ * to change the events that the event callback is looking for. The events
293
+ * parameter is an integer representing the events the user is interested in;
294
+ * it should be one or more of EVENT_READABLE, EVENT_WRITABLE, EVENT_ERROR,
295
+ * and EVENT_HANGUP, ORed together.
296
+ */
297
+ static VALUE libvirt_stream_event_update_callback(VALUE s, VALUE events)
298
+ {
299
+ ruby_libvirt_generate_call_nil(virStreamEventUpdateCallback,
300
+ ruby_libvirt_connect_get(s),
301
+ ruby_libvirt_stream_get(s), NUM2INT(events));
302
+ }
303
+
304
+ /*
305
+ * call-seq:
306
+ * stream.event_remove_callback -> nil
307
+ *
308
+ * Call virStreamEventRemoveCallback[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamEventRemoveCallback]
309
+ * to remove the event callback currently registered to this stream.
310
+ */
311
+ static VALUE libvirt_stream_event_remove_callback(VALUE s)
312
+ {
313
+ ruby_libvirt_generate_call_nil(virStreamEventRemoveCallback,
314
+ ruby_libvirt_connect_get(s),
315
+ ruby_libvirt_stream_get(s));
316
+ }
317
+
318
+ /*
319
+ * call-seq:
320
+ * stream.finish -> nil
321
+ *
322
+ * Call virStreamFinish[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamFinish]
323
+ * to finish this stream. Finish is typically used when the stream is no
324
+ * longer needed and needs to be cleaned up.
325
+ */
326
+ static VALUE libvirt_stream_finish(VALUE s)
327
+ {
328
+ ruby_libvirt_generate_call_nil(virStreamFinish, ruby_libvirt_connect_get(s),
329
+ ruby_libvirt_stream_get(s));
330
+ }
331
+
332
+ /*
333
+ * call-seq:
334
+ * stream.abort -> nil
335
+ *
336
+ * Call virStreamAbort[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamAbort]
337
+ * to abort this stream. Abort is typically used when something on the stream
338
+ * has failed, and the stream needs to be cleaned up.
339
+ */
340
+ static VALUE libvirt_stream_abort(VALUE s)
341
+ {
342
+ ruby_libvirt_generate_call_nil(virStreamAbort, ruby_libvirt_connect_get(s),
343
+ ruby_libvirt_stream_get(s));
344
+ }
345
+
346
+ /*
347
+ * call-seq:
348
+ * stream.free -> nil
349
+ *
350
+ * Call virStreamFree[http://www.libvirt.org/html/libvirt-libvirt-stream.html#virStreamFree]
351
+ * to free this stream. The object will no longer be valid after this call.
352
+ */
353
+ static VALUE libvirt_stream_free(VALUE s)
354
+ {
355
+ ruby_libvirt_generate_call_free(Stream, s);
356
+ }
357
+ #endif
358
+
359
+ /*
360
+ * Class Libvirt::Stream
361
+ */
362
+ void ruby_libvirt_stream_init(void)
363
+ {
364
+ #if HAVE_TYPE_VIRSTREAMPTR
365
+ c_stream = rb_define_class_under(m_libvirt, "Stream", rb_cObject);
366
+
367
+ rb_define_attr(c_stream, "connection", 1, 0);
368
+
369
+ rb_define_const(c_stream, "NONBLOCK", INT2NUM(VIR_STREAM_NONBLOCK));
370
+ rb_define_const(c_stream, "EVENT_READABLE",
371
+ INT2NUM(VIR_STREAM_EVENT_READABLE));
372
+ rb_define_const(c_stream, "EVENT_WRITABLE",
373
+ INT2NUM(VIR_STREAM_EVENT_WRITABLE));
374
+ rb_define_const(c_stream, "EVENT_ERROR", INT2NUM(VIR_STREAM_EVENT_ERROR));
375
+ rb_define_const(c_stream, "EVENT_HANGUP", INT2NUM(VIR_STREAM_EVENT_HANGUP));
376
+
377
+ rb_define_method(c_stream, "send", libvirt_stream_send, 1);
378
+ rb_define_method(c_stream, "recv", libvirt_stream_recv, 1);
379
+ rb_define_method(c_stream, "sendall", libvirt_stream_sendall, -1);
380
+ rb_define_method(c_stream, "recvall", libvirt_stream_recvall, -1);
381
+
382
+ rb_define_method(c_stream, "event_add_callback",
383
+ libvirt_stream_event_add_callback, -1);
384
+ rb_define_method(c_stream, "event_update_callback",
385
+ libvirt_stream_event_update_callback, 1);
386
+ rb_define_method(c_stream, "event_remove_callback",
387
+ libvirt_stream_event_remove_callback, 0);
388
+ rb_define_method(c_stream, "finish", libvirt_stream_finish, 0);
389
+ rb_define_method(c_stream, "abort", libvirt_stream_abort, 0);
390
+ rb_define_method(c_stream, "free", libvirt_stream_free, 0);
391
+ #endif
392
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef STREAM_H
2
+ #define STREAM_H
3
+
4
+ void ruby_libvirt_stream_init(void);
5
+
6
+ VALUE ruby_libvirt_stream_new(virStreamPtr s, VALUE conn);
7
+ virStreamPtr ruby_libvirt_stream_get(VALUE s);
8
+
9
+ #endif
data/lib/libvirt.rb ADDED
@@ -0,0 +1,40 @@
1
+ #
2
+ # libvirt.rb: main module for the ruby-libvirt bindings
3
+ #
4
+ # Copyright (C) 2007 Red Hat, Inc.
5
+ #
6
+ # Distributed under the GNU Lesser General Public License v2.1 or later.
7
+ # See COPYING for details
8
+ #
9
+ # David Lutterkort <dlutter@redhat.com>
10
+
11
+ require '_libvirt'
12
+
13
+ module Libvirt
14
+
15
+ # A version in Libvirt's representation
16
+ class Version
17
+ attr_reader :version, :type
18
+
19
+ def initialize(type, version)
20
+ @type = type
21
+ @version = version
22
+ end
23
+
24
+ def major
25
+ version / 1000000
26
+ end
27
+
28
+ def minor
29
+ version % 1000000 / 1000
30
+ end
31
+
32
+ def release
33
+ version % 1000
34
+ end
35
+
36
+ def to_s
37
+ "#{major}.#{minor}.#{release}"
38
+ end
39
+ end
40
+ end