ruby-libvirt 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +16 -0
- data/README +4 -16
- data/README.rdoc +1 -0
- data/Rakefile +65 -24
- data/ext/libvirt/_libvirt.c +245 -16
- data/ext/libvirt/common.c +3 -1
- data/ext/libvirt/connect.c +195 -38
- data/ext/libvirt/domain.c +871 -282
- data/ext/libvirt/domain.h +0 -3
- data/ext/libvirt/extconf.rb +81 -5
- data/ext/libvirt/interface.c +3 -3
- data/ext/libvirt/network.c +1 -1
- data/ext/libvirt/nodedevice.c +3 -1
- data/ext/libvirt/nwfilter.c +1 -1
- data/ext/libvirt/secret.c +3 -3
- data/ext/libvirt/storage.c +60 -11
- data/ext/libvirt/stream.c +394 -0
- data/ext/libvirt/stream.h +7 -0
- data/tests/test_conn.rb +470 -0
- data/tests/test_domain.rb +224 -258
- data/tests/test_interface.rb +7 -73
- data/tests/test_network.rb +15 -100
- data/tests/test_nodedevice.rb +0 -31
- data/tests/test_nwfilter.rb +6 -61
- data/tests/test_open.rb +43 -49
- data/tests/test_secret.rb +9 -65
- data/tests/test_storage.rb +35 -134
- data/tests/test_utils.rb +120 -13
- metadata +26 -26
data/ext/libvirt/domain.h
CHANGED
data/ext/libvirt/extconf.rb
CHANGED
@@ -10,6 +10,7 @@ def have_libvirt_types(types)
|
|
10
10
|
types.each { |t| have_type(t, "libvirt/libvirt.h") }
|
11
11
|
end
|
12
12
|
|
13
|
+
# older mkmf does not have checking_message, so implement our own here
|
13
14
|
def libvirt_checking_message(target, place = nil, opt = nil)
|
14
15
|
[["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
|
15
16
|
if noun
|
@@ -42,17 +43,48 @@ SRC
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def have_libvirt_consts(consts)
|
45
|
-
consts.each { |c| have_const(c, "libvirt/libvirt.h") }
|
46
|
+
consts.each { |c| have_const(c, ["libvirt/libvirt.h", "libvirt/virterror.h"]) }
|
46
47
|
end
|
47
48
|
|
48
49
|
extension_name = '_libvirt'
|
49
50
|
|
50
|
-
dir_config
|
51
|
+
# this is a poor-man's dir_config, but is a bit more flexible. In particular,
|
52
|
+
# it allows you to specify the exact location of the libvirt.so, as opposed
|
53
|
+
# to requiring a lib/ subdirectory. Note that due to the way include files
|
54
|
+
# are done within ruby-libvirt, the libvirt header file(s) must be in a libvirt/
|
55
|
+
# subdirectory. Also note that if specifying the include directory, the
|
56
|
+
# location of the library must also be specified. Finally, note that if neither
|
57
|
+
# the include nor the library are specified, the build will attempt to use
|
58
|
+
# pkg-config to discover this information.
|
59
|
+
#
|
60
|
+
# Taking all of the above rules into account, the valid options are either:
|
61
|
+
# $ ruby extconf.rb --with-libvirt-include=/home/clalance/libvirt/include \
|
62
|
+
# --with-libvirt-lib=/home/clalance/libvirt/src/.libs
|
63
|
+
#
|
64
|
+
# To specify the location of the include files and the library, or:
|
65
|
+
# $ ruby extconf.rb
|
66
|
+
#
|
67
|
+
# to attempt to use pkg-config to do it automatically from the system files.
|
68
|
+
include = with_config("libvirt-include")
|
69
|
+
lib = with_config("libvirt-lib")
|
70
|
+
if include and lib
|
71
|
+
$LIBPATH = [lib] | $LIBPATH
|
72
|
+
$CPPFLAGS += "-I" + include
|
73
|
+
have_library("virt", "virConnectOpen", "libvirt/libvirt.h")
|
51
74
|
|
52
|
-
|
53
|
-
|
75
|
+
# if we are using custom libvirt libraries, we have to suppress the default
|
76
|
+
# library path so have_func() only picks up the custom ones, not the installed
|
77
|
+
# ones
|
78
|
+
$DEFLIBPATH = []
|
79
|
+
elsif (include and not lib) or (not include and lib)
|
80
|
+
raise "Must specify both --with-libvirt-include and --with-libvirt-lib, or neither"
|
81
|
+
else
|
82
|
+
unless pkg_config("libvirt")
|
83
|
+
raise "libvirt library not found in default locations"
|
84
|
+
end
|
54
85
|
end
|
55
86
|
|
87
|
+
|
56
88
|
libvirt_types = [ 'virNetworkPtr',
|
57
89
|
'virStoragePoolPtr',
|
58
90
|
'virStorageVolPtr',
|
@@ -64,6 +96,8 @@ libvirt_types = [ 'virNetworkPtr',
|
|
64
96
|
'virDomainSnapshotPtr',
|
65
97
|
'virDomainJobInfoPtr',
|
66
98
|
'virNodeDevicePtr',
|
99
|
+
'virStreamPtr',
|
100
|
+
'virTypedParameterPtr',
|
67
101
|
]
|
68
102
|
|
69
103
|
libvirt_funcs = [ 'virStorageVolWipe',
|
@@ -102,6 +136,18 @@ libvirt_funcs = [ 'virStorageVolWipe',
|
|
102
136
|
'virDomainMemoryPeek',
|
103
137
|
'virConnectOpenAuth',
|
104
138
|
'virEventRegisterImpl',
|
139
|
+
'virDomainIsUpdated',
|
140
|
+
'virDomainSetMemoryParameters',
|
141
|
+
'virConnectGetSysinfo',
|
142
|
+
'virDomainSetBlkioParameters',
|
143
|
+
'virDomainSetMemoryFlags',
|
144
|
+
'virDomainGetState',
|
145
|
+
'virDomainOpenConsole',
|
146
|
+
'virDomainMigrate2',
|
147
|
+
'virDomainScreenshot',
|
148
|
+
'virInterfaceChangeBegin',
|
149
|
+
'virStorageVolDownload',
|
150
|
+
'virDomainInjectNMI',
|
105
151
|
]
|
106
152
|
|
107
153
|
libvirt_consts = [ 'VIR_MIGRATE_LIVE',
|
@@ -118,6 +164,7 @@ libvirt_consts = [ 'VIR_MIGRATE_LIVE',
|
|
118
164
|
'VIR_DUMP_CRASH',
|
119
165
|
'VIR_DUMP_LIVE',
|
120
166
|
'VIR_DOMAIN_DEVICE_MODIFY_CURRENT',
|
167
|
+
'VIR_DOMAIN_DEVICE_MODIFY_LIVE',
|
121
168
|
'VIR_DOMAIN_DEVICE_MODIFY_CONFIG',
|
122
169
|
'VIR_DOMAIN_DEVICE_MODIFY_FORCE',
|
123
170
|
'VIR_INTERFACE_XML_INACTIVE',
|
@@ -131,12 +178,41 @@ libvirt_consts = [ 'VIR_MIGRATE_LIVE',
|
|
131
178
|
'VIR_DOMAIN_EVENT_ID_REBOOT',
|
132
179
|
'VIR_DOMAIN_EVENT_ID_RTC_CHANGE',
|
133
180
|
'VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON',
|
181
|
+
'VIR_FROM_VMWARE',
|
182
|
+
'VIR_FROM_AUDIT',
|
183
|
+
'VIR_FROM_SYSINFO',
|
184
|
+
'VIR_FROM_STREAMS',
|
185
|
+
'VIR_FROM_XENAPI',
|
186
|
+
'VIR_FROM_HOOK',
|
187
|
+
'VIR_ERR_HOOK_SCRIPT_FAILED',
|
188
|
+
'VIR_ERR_MIGRATE_PERSIST_FAILED',
|
189
|
+
'VIR_ERR_OPERATION_TIMEOUT',
|
190
|
+
'VIR_ERR_CONFIG_UNSUPPORTED',
|
191
|
+
'VIR_FROM_XENXM',
|
192
|
+
'VIR_ERR_OPERATION_INVALID',
|
193
|
+
'VIR_ERR_NO_SECURITY_MODEL',
|
194
|
+
'VIR_ERR_AUTH_FAILED',
|
195
|
+
'VIR_FROM_PHYP',
|
196
|
+
'VIR_FROM_ESX',
|
197
|
+
'VIR_FROM_ONE',
|
198
|
+
'VIR_FROM_VBOX',
|
199
|
+
'VIR_FROM_LXC',
|
200
|
+
'VIR_FROM_UML',
|
201
|
+
'VIR_FROM_NETWORK',
|
202
|
+
'VIR_FROM_DOMAIN',
|
203
|
+
'VIR_FROM_STATS_LINUX',
|
204
|
+
'VIR_FROM_XEN_INOTIFY',
|
205
|
+
'VIR_FROM_SECURITY',
|
206
|
+
'VIR_DOMAIN_AFFECT_CURRENT',
|
207
|
+
'VIR_DOMAIN_MEM_CURRENT',
|
208
|
+
'VIR_DOMAIN_EVENT_ID_CONTROL_ERROR',
|
134
209
|
]
|
135
210
|
|
136
211
|
have_libvirt_types(libvirt_types)
|
137
212
|
have_libvirt_funcs(libvirt_funcs)
|
138
213
|
if find_header("libvirt/libvirt-qemu.h")
|
139
|
-
|
214
|
+
have_library("virt-qemu", "virDomainQemuMonitorCommand")
|
215
|
+
have_func("virDomainQemuMonitorCommand", "libvirt/libvirt-qemu.h")
|
140
216
|
end
|
141
217
|
|
142
218
|
have_libvirt_consts(libvirt_consts)
|
data/ext/libvirt/interface.c
CHANGED
@@ -63,7 +63,7 @@ static VALUE libvirt_interface_create(int argc, VALUE *argv, VALUE s) {
|
|
63
63
|
|
64
64
|
rb_scan_args(argc, argv, "01", &flags);
|
65
65
|
if (NIL_P(flags))
|
66
|
-
flags =
|
66
|
+
flags = INT2NUM(0);
|
67
67
|
|
68
68
|
gen_call_void(virInterfaceCreate, conn(s), interface_get(s),
|
69
69
|
NUM2UINT(flags));
|
@@ -81,7 +81,7 @@ static VALUE libvirt_interface_destroy(int argc, VALUE *argv, VALUE s) {
|
|
81
81
|
|
82
82
|
rb_scan_args(argc, argv, "01", &flags);
|
83
83
|
if (NIL_P(flags))
|
84
|
-
flags =
|
84
|
+
flags = INT2NUM(0);
|
85
85
|
|
86
86
|
gen_call_void(virInterfaceDestroy, conn(s), interface_get(s),
|
87
87
|
NUM2UINT(flags));
|
@@ -135,7 +135,7 @@ static VALUE libvirt_interface_xml_desc(int argc, VALUE *argv, VALUE s) {
|
|
135
135
|
rb_scan_args(argc, argv, "01", &flags);
|
136
136
|
|
137
137
|
if (NIL_P(flags))
|
138
|
-
flags =
|
138
|
+
flags = INT2NUM(0);
|
139
139
|
|
140
140
|
gen_call_string(virInterfaceGetXMLDesc, conn(s), 1, interface_get(s),
|
141
141
|
NUM2UINT(flags));
|
data/ext/libvirt/network.c
CHANGED
@@ -116,7 +116,7 @@ static VALUE libvirt_netw_xml_desc(int argc, VALUE *argv, VALUE s) {
|
|
116
116
|
rb_scan_args(argc, argv, "01", &flags);
|
117
117
|
|
118
118
|
if (NIL_P(flags))
|
119
|
-
flags =
|
119
|
+
flags = INT2NUM(0);
|
120
120
|
|
121
121
|
gen_call_string(virNetworkGetXMLDesc, conn(s), 1, network_get(s),
|
122
122
|
NUM2UINT(flags));
|
data/ext/libvirt/nodedevice.c
CHANGED
@@ -127,7 +127,7 @@ static VALUE libvirt_nodedevice_xml_desc(int argc, VALUE *argv, VALUE s) {
|
|
127
127
|
rb_scan_args(argc, argv, "01", &flags);
|
128
128
|
|
129
129
|
if (NIL_P(flags))
|
130
|
-
flags =
|
130
|
+
flags = INT2NUM(0);
|
131
131
|
|
132
132
|
gen_call_string(virNodeDeviceGetXMLDesc, conn(s), 1,
|
133
133
|
nodedevice_get(s), NUM2UINT(flags));
|
@@ -200,6 +200,8 @@ void init_nodedevice()
|
|
200
200
|
#if HAVE_TYPE_VIRNODEDEVICEPTR
|
201
201
|
c_nodedevice = rb_define_class_under(m_libvirt, "NodeDevice", rb_cObject);
|
202
202
|
|
203
|
+
rb_define_attr(c_nodedevice, "connection", 1, 0);
|
204
|
+
|
203
205
|
rb_define_method(c_nodedevice, "name", libvirt_nodedevice_name, 0);
|
204
206
|
rb_define_method(c_nodedevice, "parent", libvirt_nodedevice_parent, 0);
|
205
207
|
rb_define_method(c_nodedevice, "num_of_caps",
|
data/ext/libvirt/nwfilter.c
CHANGED
@@ -94,7 +94,7 @@ static VALUE libvirt_nwfilter_xml_desc(int argc, VALUE *argv, VALUE s) {
|
|
94
94
|
rb_scan_args(argc, argv, "01", &flags);
|
95
95
|
|
96
96
|
if (NIL_P(flags))
|
97
|
-
flags =
|
97
|
+
flags = INT2NUM(0);
|
98
98
|
|
99
99
|
gen_call_string(virNWFilterGetXMLDesc, conn(s), 1, nwfilter_get(s),
|
100
100
|
NUM2UINT(flags));
|
data/ext/libvirt/secret.c
CHANGED
@@ -93,7 +93,7 @@ static VALUE libvirt_secret_xml_desc(int argc, VALUE *argv, VALUE s) {
|
|
93
93
|
rb_scan_args(argc, argv, "01", &flags);
|
94
94
|
|
95
95
|
if (NIL_P(flags))
|
96
|
-
flags =
|
96
|
+
flags = INT2NUM(0);
|
97
97
|
|
98
98
|
gen_call_string(virSecretGetXMLDesc, conn(s), 1, secret_get(s),
|
99
99
|
NUM2UINT(flags));
|
@@ -113,7 +113,7 @@ static VALUE libvirt_secret_set_value(int argc, VALUE *argv, VALUE s) {
|
|
113
113
|
rb_scan_args(argc, argv, "11", &value, &flags);
|
114
114
|
|
115
115
|
if (NIL_P(flags))
|
116
|
-
flags =
|
116
|
+
flags = INT2NUM(0);
|
117
117
|
|
118
118
|
StringValue(value);
|
119
119
|
|
@@ -141,7 +141,7 @@ static VALUE libvirt_secret_get_value(int argc, VALUE *argv, VALUE s) {
|
|
141
141
|
rb_scan_args(argc, argv, "01", &flags);
|
142
142
|
|
143
143
|
if (NIL_P(flags))
|
144
|
-
flags =
|
144
|
+
flags = INT2NUM(0);
|
145
145
|
|
146
146
|
val = virSecretGetValue(secret, &value_size, NUM2UINT(flags));
|
147
147
|
|
data/ext/libvirt/storage.c
CHANGED
@@ -24,6 +24,7 @@
|
|
24
24
|
#include "common.h"
|
25
25
|
#include "connect.h"
|
26
26
|
#include "extconf.h"
|
27
|
+
#include "stream.h"
|
27
28
|
|
28
29
|
#if HAVE_TYPE_VIRSTORAGEVOLPTR
|
29
30
|
/* this has to be here (as opposed to below with the rest of the volume
|
@@ -84,7 +85,7 @@ static VALUE libvirt_pool_build(int argc, VALUE *argv, VALUE p) {
|
|
84
85
|
rb_scan_args(argc, argv, "01", &flags);
|
85
86
|
|
86
87
|
if (NIL_P(flags))
|
87
|
-
flags =
|
88
|
+
flags = INT2NUM(0);
|
88
89
|
|
89
90
|
gen_call_void(virStoragePoolBuild, conn(p), pool_get(p), NUM2UINT(flags));
|
90
91
|
}
|
@@ -113,7 +114,7 @@ static VALUE libvirt_pool_create(int argc, VALUE *argv, VALUE p) {
|
|
113
114
|
rb_scan_args(argc, argv, "01", &flags);
|
114
115
|
|
115
116
|
if (NIL_P(flags))
|
116
|
-
flags =
|
117
|
+
flags = INT2NUM(0);
|
117
118
|
|
118
119
|
gen_call_void(virStoragePoolCreate, conn(p), pool_get(p), NUM2UINT(flags));
|
119
120
|
}
|
@@ -143,7 +144,7 @@ static VALUE libvirt_pool_delete(int argc, VALUE *argv, VALUE p) {
|
|
143
144
|
rb_scan_args(argc, argv, "01", &flags);
|
144
145
|
|
145
146
|
if (NIL_P(flags))
|
146
|
-
flags =
|
147
|
+
flags = INT2NUM(0);
|
147
148
|
|
148
149
|
gen_call_void(virStoragePoolDelete, conn(p), pool_get(p), NUM2UINT(flags));
|
149
150
|
}
|
@@ -161,7 +162,7 @@ static VALUE libvirt_pool_refresh(int argc, VALUE *argv, VALUE p) {
|
|
161
162
|
rb_scan_args(argc, argv, "01", &flags);
|
162
163
|
|
163
164
|
if (NIL_P(flags))
|
164
|
-
flags =
|
165
|
+
flags = INT2NUM(0);
|
165
166
|
|
166
167
|
gen_call_void(virStoragePoolRefresh, conn(p), pool_get(p), NUM2UINT(flags));
|
167
168
|
}
|
@@ -211,7 +212,7 @@ static VALUE libvirt_pool_info(VALUE s) {
|
|
211
212
|
_E(r < 0, create_error(e_RetrieveError, "virStoragePoolGetInfo", conn(s)));
|
212
213
|
|
213
214
|
result = rb_class_new_instance(0, NULL, c_storage_pool_info);
|
214
|
-
rb_iv_set(result, "@state",
|
215
|
+
rb_iv_set(result, "@state", INT2NUM(info.state));
|
215
216
|
rb_iv_set(result, "@capacity", ULL2NUM(info.capacity));
|
216
217
|
rb_iv_set(result, "@allocation", ULL2NUM(info.allocation));
|
217
218
|
rb_iv_set(result, "@available", ULL2NUM(info.available));
|
@@ -232,7 +233,7 @@ static VALUE libvirt_pool_xml_desc(int argc, VALUE *argv, VALUE s) {
|
|
232
233
|
rb_scan_args(argc, argv, "01", &flags);
|
233
234
|
|
234
235
|
if (NIL_P(flags))
|
235
|
-
flags =
|
236
|
+
flags = INT2NUM(0);
|
236
237
|
|
237
238
|
gen_call_string(virStoragePoolGetXMLDesc, conn(s), 1, pool_get(s),
|
238
239
|
NUM2UINT(flags));
|
@@ -433,7 +434,7 @@ static VALUE libvirt_pool_vol_create_xml(int argc, VALUE *argv, VALUE p) {
|
|
433
434
|
rb_scan_args(argc, argv, "11", &xml, &flags);
|
434
435
|
|
435
436
|
if (NIL_P(flags))
|
436
|
-
flags =
|
437
|
+
flags = INT2NUM(0);
|
437
438
|
|
438
439
|
vol = virStorageVolCreateXML(pool_get(p), StringValueCStr(xml),
|
439
440
|
NUM2UINT(flags));
|
@@ -459,7 +460,7 @@ static VALUE libvirt_pool_vol_create_xml_from(int argc, VALUE *argv, VALUE p) {
|
|
459
460
|
rb_scan_args(argc, argv, "21", &xml, &cloneval, &flags);
|
460
461
|
|
461
462
|
if (NIL_P(flags))
|
462
|
-
flags =
|
463
|
+
flags = INT2NUM(0);
|
463
464
|
|
464
465
|
vol = virStorageVolCreateXMLFrom(pool_get(p), StringValueCStr(xml),
|
465
466
|
vol_get(cloneval), NUM2UINT(flags));
|
@@ -508,7 +509,7 @@ static VALUE libvirt_vol_delete(int argc, VALUE *argv, VALUE v) {
|
|
508
509
|
rb_scan_args(argc, argv, "01", &flags);
|
509
510
|
|
510
511
|
if (NIL_P(flags))
|
511
|
-
flags =
|
512
|
+
flags = INT2NUM(0);
|
512
513
|
|
513
514
|
gen_call_void(virStorageVolDelete, conn(v), vol_get(v), NUM2UINT(flags));
|
514
515
|
}
|
@@ -527,7 +528,7 @@ static VALUE libvirt_vol_wipe(int argc, VALUE *argv, VALUE v) {
|
|
527
528
|
rb_scan_args(argc, argv, "01", &flags);
|
528
529
|
|
529
530
|
if (NIL_P(flags))
|
530
|
-
flags =
|
531
|
+
flags = INT2NUM(0);
|
531
532
|
|
532
533
|
gen_call_void(virStorageVolWipe, conn(v), vol_get(v), NUM2UINT(flags));
|
533
534
|
}
|
@@ -569,7 +570,7 @@ static VALUE libvirt_vol_xml_desc(int argc, VALUE *argv, VALUE v) {
|
|
569
570
|
rb_scan_args(argc, argv, "01", &flags);
|
570
571
|
|
571
572
|
if (NIL_P(flags))
|
572
|
-
flags =
|
573
|
+
flags = INT2NUM(0);
|
573
574
|
|
574
575
|
gen_call_string(virStorageVolGetXMLDesc, conn(v), 1, vol_get(v),
|
575
576
|
NUM2UINT(flags));
|
@@ -599,6 +600,46 @@ static VALUE libvirt_vol_free(VALUE s) {
|
|
599
600
|
}
|
600
601
|
#endif
|
601
602
|
|
603
|
+
#if HAVE_VIRSTORAGEVOLDOWNLOAD
|
604
|
+
/*
|
605
|
+
* call-seq:
|
606
|
+
* vol.download(stream, offset, length, flags=0) -> nil
|
607
|
+
*
|
608
|
+
* Call +virStorageVolDownload+[http://www.libvirt.org/html/libvirt-libvirt.html#virStorageVolDownload]
|
609
|
+
* to download the content of a volume as a stream.
|
610
|
+
*/
|
611
|
+
static VALUE libvirt_vol_download(int argc, VALUE *argv, VALUE v) {
|
612
|
+
VALUE st, offset, length, flags;
|
613
|
+
|
614
|
+
rb_scan_args(argc, argv, "31", &st, &offset, &length, &flags);
|
615
|
+
|
616
|
+
if (NIL_P(flags))
|
617
|
+
flags = INT2NUM(0);
|
618
|
+
|
619
|
+
gen_call_void(virStorageVolDownload, conn(v), vol_get(v), stream_get(st),
|
620
|
+
NUM2ULL(offset), NUM2ULL(length), NUM2UINT(flags));
|
621
|
+
}
|
622
|
+
|
623
|
+
/*
|
624
|
+
* call-seq:
|
625
|
+
* vol.upload(stream, offset, length, flags=0) -> nil
|
626
|
+
*
|
627
|
+
* Call +virStorageVolUpload+[http://www.libvirt.org/html/libvirt-libvirt.html#virStorageVolUpload]
|
628
|
+
* to upload new content to a volume from a stream.
|
629
|
+
*/
|
630
|
+
static VALUE libvirt_vol_upload(int argc, VALUE *argv, VALUE v) {
|
631
|
+
VALUE st, offset, length, flags;
|
632
|
+
|
633
|
+
rb_scan_args(argc, argv, "31", &st, &offset, &length, &flags);
|
634
|
+
|
635
|
+
if (NIL_P(flags))
|
636
|
+
flags = INT2NUM(0);
|
637
|
+
|
638
|
+
gen_call_void(virStorageVolUpload, conn(v), vol_get(v), stream_get(st),
|
639
|
+
NUM2ULL(offset), NUM2ULL(length), NUM2UINT(flags));
|
640
|
+
}
|
641
|
+
#endif
|
642
|
+
|
602
643
|
void init_storage(void) {
|
603
644
|
/*
|
604
645
|
* Class Libvirt::StoragePool and Libvirt::StoragePoolInfo
|
@@ -614,6 +655,8 @@ void init_storage(void) {
|
|
614
655
|
c_storage_pool = rb_define_class_under(m_libvirt, "StoragePool",
|
615
656
|
rb_cObject);
|
616
657
|
|
658
|
+
rb_define_attr(c_storage_pool, "connection", 1, 0);
|
659
|
+
|
617
660
|
/* virStoragePoolState */
|
618
661
|
rb_define_const(c_storage_pool, "INACTIVE",
|
619
662
|
INT2NUM(VIR_STORAGE_POOL_INACTIVE));
|
@@ -723,5 +766,11 @@ void init_storage(void) {
|
|
723
766
|
rb_define_method(c_storage_vol, "xml_desc", libvirt_vol_xml_desc, -1);
|
724
767
|
rb_define_method(c_storage_vol, "path", libvirt_vol_path, 0);
|
725
768
|
rb_define_method(c_storage_vol, "free", libvirt_vol_free, 0);
|
769
|
+
|
770
|
+
#if HAVE_VIRSTORAGEVOLDOWNLOAD
|
771
|
+
rb_define_method(c_storage_vol, "download", libvirt_vol_download, -1);
|
772
|
+
rb_define_method(c_storage_vol, "upload", libvirt_vol_upload, -1);
|
773
|
+
#endif
|
774
|
+
|
726
775
|
#endif
|
727
776
|
}
|
@@ -0,0 +1,394 @@
|
|
1
|
+
/*
|
2
|
+
* stream.c: virStream methods
|
3
|
+
*
|
4
|
+
* Copyright (C) 2007,2010 Red Hat Inc.
|
5
|
+
*
|
6
|
+
* This library is free software; you can redistribute it and/or
|
7
|
+
* modify it under the terms of the GNU Lesser General Public
|
8
|
+
* License as published by the Free Software Foundation; either
|
9
|
+
* version 2.1 of the License, or (at your option) any later version.
|
10
|
+
*
|
11
|
+
* This library is distributed in the hope that it will be useful,
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14
|
+
* Lesser General Public License for more details.
|
15
|
+
*
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
17
|
+
* License along with this library; if not, write to the Free Software
|
18
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
*/
|
20
|
+
|
21
|
+
#include <ruby.h>
|
22
|
+
#include <libvirt/libvirt.h>
|
23
|
+
#include <libvirt/virterror.h>
|
24
|
+
#include "common.h"
|
25
|
+
#include "connect.h"
|
26
|
+
#include "extconf.h"
|
27
|
+
|
28
|
+
#if HAVE_TYPE_VIRSTREAMPTR
|
29
|
+
static VALUE c_stream;
|
30
|
+
|
31
|
+
static void stream_free(void *s) {
|
32
|
+
generic_free(Stream, s);
|
33
|
+
}
|
34
|
+
|
35
|
+
virStreamPtr stream_get(VALUE s) {
|
36
|
+
generic_get(Stream, s);
|
37
|
+
}
|
38
|
+
|
39
|
+
VALUE stream_new(virStreamPtr s, VALUE conn) {
|
40
|
+
return generic_new(c_stream, s, conn, stream_free);
|
41
|
+
}
|
42
|
+
|
43
|
+
/*
|
44
|
+
* call-seq:
|
45
|
+
* stream.send(buffer) -> Fixnum
|
46
|
+
*
|
47
|
+
* Call +virStreamSend+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamSend]
|
48
|
+
* to send the data in buffer out to the stream. The return value is the
|
49
|
+
* number of bytes sent, which may be less than the size of the buffer. If
|
50
|
+
* an error occurred, -1 is returned. If the transmit buffers are full and the
|
51
|
+
* stream is marked non-blocking, returns -2.
|
52
|
+
*/
|
53
|
+
static VALUE libvirt_stream_send(VALUE s, VALUE buffer) {
|
54
|
+
int ret;
|
55
|
+
|
56
|
+
StringValue(buffer);
|
57
|
+
|
58
|
+
ret = virStreamSend(stream_get(s), RSTRING_PTR(buffer),
|
59
|
+
RSTRING_LEN(buffer));
|
60
|
+
_E(ret == -1, create_error(e_RetrieveError, "virStreamSend", conn(s)));
|
61
|
+
|
62
|
+
return INT2NUM(ret);
|
63
|
+
}
|
64
|
+
|
65
|
+
struct stream_recv_args {
|
66
|
+
int ret;
|
67
|
+
char *data;
|
68
|
+
};
|
69
|
+
|
70
|
+
static VALUE stream_recv_array(VALUE input) {
|
71
|
+
VALUE result;
|
72
|
+
struct stream_recv_args *args = (struct stream_recv_args *)input;
|
73
|
+
|
74
|
+
result = rb_ary_new();
|
75
|
+
|
76
|
+
rb_ary_push(result, INT2NUM(args->ret));
|
77
|
+
rb_ary_push(result, rb_str_new(args->data, args->ret));
|
78
|
+
|
79
|
+
return result;
|
80
|
+
}
|
81
|
+
|
82
|
+
/*
|
83
|
+
* call-seq:
|
84
|
+
* stream.recv(bytes) -> [return_value, data]
|
85
|
+
*
|
86
|
+
* Call +virStreamRecv+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamRecv]
|
87
|
+
* to receive up to bytes amount of data from the stream. The return is an
|
88
|
+
* array with two elements; the return code from the virStreamRecv call and
|
89
|
+
* the data (as a String) read from the stream. If an error occurred, the
|
90
|
+
* return_value is set to -1. If there is no data pending and the stream is
|
91
|
+
* marked as non-blocking, return_value is set to -2.
|
92
|
+
*/
|
93
|
+
static VALUE libvirt_stream_recv(VALUE s, VALUE bytes) {
|
94
|
+
char *data;
|
95
|
+
int ret;
|
96
|
+
int exception = 0;
|
97
|
+
VALUE result;
|
98
|
+
struct stream_recv_args args;
|
99
|
+
|
100
|
+
data = ALLOC_N(char, NUM2INT(bytes));
|
101
|
+
|
102
|
+
ret = virStreamRecv(stream_get(s), data, NUM2INT(bytes));
|
103
|
+
if (ret == -1) {
|
104
|
+
xfree(data);
|
105
|
+
rb_exc_raise(create_error(e_RetrieveError, "virStreamRecv", conn(s)));
|
106
|
+
}
|
107
|
+
|
108
|
+
args.ret = ret;
|
109
|
+
args.data = data;
|
110
|
+
result = rb_protect(stream_recv_array, (VALUE)&args, &exception);
|
111
|
+
if (exception) {
|
112
|
+
xfree(data);
|
113
|
+
rb_jump_tag(exception);
|
114
|
+
}
|
115
|
+
|
116
|
+
xfree(data);
|
117
|
+
return result;
|
118
|
+
}
|
119
|
+
|
120
|
+
static int internal_sendall(virStreamPtr st, char *data, size_t nbytes,
|
121
|
+
void *opaque) {
|
122
|
+
VALUE result;
|
123
|
+
VALUE retcode, buffer;
|
124
|
+
|
125
|
+
result = rb_yield_values(2, (VALUE)opaque, INT2NUM(nbytes));
|
126
|
+
|
127
|
+
if (TYPE(result) != T_ARRAY)
|
128
|
+
rb_raise(rb_eTypeError, "wrong type (expected Array)");
|
129
|
+
|
130
|
+
if (RARRAY_LEN(result) != 2)
|
131
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)",
|
132
|
+
RARRAY_LEN(result));
|
133
|
+
|
134
|
+
retcode = rb_ary_entry(result, 0);
|
135
|
+
buffer = rb_ary_entry(result, 1);
|
136
|
+
|
137
|
+
if (NUM2INT(retcode) < 0)
|
138
|
+
return NUM2INT(retcode);
|
139
|
+
|
140
|
+
StringValue(buffer);
|
141
|
+
|
142
|
+
if (RSTRING_LEN(buffer) > nbytes)
|
143
|
+
rb_raise(rb_eArgError, "asked for %d bytes, block returned %d", nbytes,
|
144
|
+
RSTRING_LEN(buffer));
|
145
|
+
|
146
|
+
memcpy(data, RSTRING_PTR(buffer), RSTRING_LEN(buffer));
|
147
|
+
|
148
|
+
return NUM2INT(retcode);
|
149
|
+
}
|
150
|
+
|
151
|
+
/*
|
152
|
+
* call-seq:
|
153
|
+
* stream.sendall(opaque=nil){|opaque, nbytes| send block} -> nil
|
154
|
+
*
|
155
|
+
* Call +virStreamSendAll+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamSendAll]
|
156
|
+
* to send the entire data stream. The send block is required and is executed
|
157
|
+
* one or more times to send data. Each invocation of the send block yields
|
158
|
+
* the opaque data passed into the initial call and the number of bytes this
|
159
|
+
* iteration is prepared to handle. The send block should return an array of
|
160
|
+
* 2 elements; the first element should be the return code from the block
|
161
|
+
* (-1 for error, 0 otherwise), and the second element should be the data
|
162
|
+
* that the block prepared to send.
|
163
|
+
*/
|
164
|
+
static VALUE libvirt_stream_sendall(int argc, VALUE *argv, VALUE s) {
|
165
|
+
VALUE opaque;
|
166
|
+
int ret;
|
167
|
+
|
168
|
+
if (!rb_block_given_p())
|
169
|
+
rb_raise(rb_eRuntimeError, "A block must be provided");
|
170
|
+
|
171
|
+
rb_scan_args(argc, argv, "01", &opaque);
|
172
|
+
|
173
|
+
ret = virStreamSendAll(stream_get(s), internal_sendall, (void *)opaque);
|
174
|
+
_E(ret < 0, create_error(e_RetrieveError, "virStreamSendAll", conn(s)));
|
175
|
+
|
176
|
+
return Qnil;
|
177
|
+
}
|
178
|
+
|
179
|
+
static int internal_recvall(virStreamPtr st, const char *buf, size_t nbytes,
|
180
|
+
void *opaque) {
|
181
|
+
VALUE result;
|
182
|
+
|
183
|
+
result = rb_yield_values(2, rb_str_new(buf, nbytes), (VALUE)opaque);
|
184
|
+
|
185
|
+
if (TYPE(result) != T_FIXNUM)
|
186
|
+
rb_raise(rb_eArgError, "wrong type (expected an integer)");
|
187
|
+
|
188
|
+
return NUM2INT(result);
|
189
|
+
}
|
190
|
+
|
191
|
+
/*
|
192
|
+
* call-seq:
|
193
|
+
* stream.recvall(opaque){|data, opaque| receive block} -> nil
|
194
|
+
*
|
195
|
+
* Call +virStreamRecvAll+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamRecvAll]
|
196
|
+
* to receive the entire data stream. The receive block is required and is
|
197
|
+
* called one or more times to receive data. Each invocation of the receive
|
198
|
+
* block yields the data received and the opaque data passed into the initial
|
199
|
+
* call. The block should return -1 if an error occurred and 0 otherwise.
|
200
|
+
*/
|
201
|
+
static VALUE libvirt_stream_recvall(int argc, VALUE *argv, VALUE s) {
|
202
|
+
VALUE opaque;
|
203
|
+
int ret;
|
204
|
+
|
205
|
+
if (!rb_block_given_p())
|
206
|
+
rb_raise(rb_eRuntimeError, "A block must be provided");
|
207
|
+
|
208
|
+
rb_scan_args(argc, argv, "01", &opaque);
|
209
|
+
|
210
|
+
ret = virStreamRecvAll(stream_get(s), internal_recvall, (void *)opaque);
|
211
|
+
_E(ret < 0, create_error(e_RetrieveError, "virStreamRecvAll", conn(s)));
|
212
|
+
|
213
|
+
return Qnil;
|
214
|
+
}
|
215
|
+
|
216
|
+
static void stream_event_callback(virStreamPtr st, int events, void *opaque) {
|
217
|
+
VALUE passthrough = (VALUE)opaque;
|
218
|
+
VALUE cb;
|
219
|
+
VALUE cb_opaque;
|
220
|
+
VALUE news;
|
221
|
+
VALUE s;
|
222
|
+
|
223
|
+
if (TYPE(passthrough) != T_ARRAY)
|
224
|
+
rb_raise(rb_eTypeError,
|
225
|
+
"wrong domain event lifecycle callback argument type (expected Array)");
|
226
|
+
|
227
|
+
if (RARRAY_LEN(passthrough) != 3)
|
228
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 3)",
|
229
|
+
RARRAY_LEN(passthrough));
|
230
|
+
|
231
|
+
cb = rb_ary_entry(passthrough, 0);
|
232
|
+
cb_opaque = rb_ary_entry(passthrough, 1);
|
233
|
+
s = rb_ary_entry(passthrough, 2);
|
234
|
+
|
235
|
+
news = stream_new(st, conn_attr(s));
|
236
|
+
if (strcmp(rb_obj_classname(cb), "Symbol") == 0)
|
237
|
+
rb_funcall(rb_class_of(cb), rb_to_id(cb), 3, news, INT2NUM(events),
|
238
|
+
cb_opaque);
|
239
|
+
else if (strcmp(rb_obj_classname(cb), "Proc") == 0)
|
240
|
+
rb_funcall(cb, rb_intern("call"), 3, news, INT2NUM(events), cb_opaque);
|
241
|
+
else
|
242
|
+
rb_raise(rb_eTypeError,
|
243
|
+
"wrong stream event callback (expected Symbol or Proc)");
|
244
|
+
}
|
245
|
+
|
246
|
+
/*
|
247
|
+
* call-seq:
|
248
|
+
* stream.event_add_callback(events, callback, opaque=nil) -> nil
|
249
|
+
*
|
250
|
+
* Call +virStreamEventAddCallback+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamEventAddCallback]
|
251
|
+
* to register a callback to be notified when a stream becomes readable or
|
252
|
+
* writeable. The events parameter is an integer representing the events the
|
253
|
+
* user is interested in; it should be one or more of EVENT_READABLE,
|
254
|
+
* EVENT_WRITABLE, EVENT_ERROR, and EVENT_HANGUP, ORed together. The callback
|
255
|
+
* can either be a Symbol (that is the name of a method to callback) or a Proc.
|
256
|
+
* The callback should accept 3 parameters: a pointer to the Stream object
|
257
|
+
* itself, the integer that represents the events that actually occurred, and
|
258
|
+
* an opaque pointer that was (optionally) passed into
|
259
|
+
* stream.event_add_callback to begin with.
|
260
|
+
*/
|
261
|
+
static VALUE libvirt_stream_event_add_callback(int argc, VALUE *argv, VALUE s) {
|
262
|
+
VALUE events;
|
263
|
+
VALUE callback;
|
264
|
+
VALUE opaque;
|
265
|
+
VALUE passthrough;
|
266
|
+
int ret;
|
267
|
+
|
268
|
+
rb_scan_args(argc, argv, "21", &events, &callback, &opaque);
|
269
|
+
|
270
|
+
if (!is_symbol_or_proc(callback))
|
271
|
+
rb_raise(rb_eTypeError, "wrong argument type (expected Symbol or Proc)");
|
272
|
+
|
273
|
+
passthrough = rb_ary_new();
|
274
|
+
rb_ary_store(passthrough, 0, callback);
|
275
|
+
rb_ary_store(passthrough, 1, opaque);
|
276
|
+
rb_ary_store(passthrough, 2, s);
|
277
|
+
|
278
|
+
ret = virStreamEventAddCallback(stream_get(s), NUM2INT(events),
|
279
|
+
stream_event_callback, (void *)passthrough,
|
280
|
+
NULL);
|
281
|
+
_E(ret < 0, create_error(e_RetrieveError, "virStreamEventAddCallback",
|
282
|
+
conn(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.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
|
+
int ret;
|
299
|
+
|
300
|
+
ret = virStreamEventUpdateCallback(stream_get(s), NUM2INT(events));
|
301
|
+
_E(ret < 0, create_error(e_RetrieveError, "virStreamEventUpdateCallback",
|
302
|
+
conn(s)));
|
303
|
+
|
304
|
+
return Qnil;
|
305
|
+
}
|
306
|
+
|
307
|
+
/*
|
308
|
+
* call-seq:
|
309
|
+
* stream.event_remove_callback -> nil
|
310
|
+
*
|
311
|
+
* Call +virStreamEventRemoveCallback+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamEventRemoveCallback]
|
312
|
+
* to remove the event callback currently registered to this stream.
|
313
|
+
*/
|
314
|
+
static VALUE libvirt_stream_event_remove_callback(VALUE s) {
|
315
|
+
int ret;
|
316
|
+
|
317
|
+
ret = virStreamEventRemoveCallback(stream_get(s));
|
318
|
+
_E(ret < 0, create_error(e_RetrieveError, "virStreamEventRemoveCallback",
|
319
|
+
conn(s)));
|
320
|
+
|
321
|
+
return Qnil;
|
322
|
+
}
|
323
|
+
|
324
|
+
/*
|
325
|
+
* call-seq:
|
326
|
+
* stream.finish -> nil
|
327
|
+
*
|
328
|
+
* Call +virStreamFinish+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamFinish]
|
329
|
+
* to finish this stream. Finish is typically used when the stream is no
|
330
|
+
* longer needed and needs to be cleaned up.
|
331
|
+
*/
|
332
|
+
static VALUE libvirt_stream_finish(VALUE s) {
|
333
|
+
gen_call_void(virStreamFinish, conn(s), stream_get(s));
|
334
|
+
}
|
335
|
+
|
336
|
+
/*
|
337
|
+
* call-seq:
|
338
|
+
* stream.abort -> nil
|
339
|
+
*
|
340
|
+
* Call +virStreamAbort+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamAbort]
|
341
|
+
* to abort this stream. Abort is typically used when something on the stream
|
342
|
+
* has failed, and the stream needs to be cleaned up.
|
343
|
+
*/
|
344
|
+
static VALUE libvirt_stream_abort(VALUE s) {
|
345
|
+
gen_call_void(virStreamAbort, conn(s), stream_get(s));
|
346
|
+
}
|
347
|
+
|
348
|
+
/*
|
349
|
+
* call-seq:
|
350
|
+
* stream.free -> nil
|
351
|
+
*
|
352
|
+
* Call +virStreamFree+[http://www.libvirt.org/html/libvirt-libvirt.html#virStreamFree]
|
353
|
+
* to free this stream. The object will no longer be valid after this call.
|
354
|
+
*/
|
355
|
+
static VALUE libvirt_stream_free(VALUE s) {
|
356
|
+
gen_call_free(Stream, s);
|
357
|
+
}
|
358
|
+
#endif
|
359
|
+
|
360
|
+
/*
|
361
|
+
* Class Libvirt::Domain
|
362
|
+
*/
|
363
|
+
void init_stream()
|
364
|
+
{
|
365
|
+
#if HAVE_TYPE_VIRSTREAMPTR
|
366
|
+
c_stream = rb_define_class_under(m_libvirt, "Stream", rb_cObject);
|
367
|
+
|
368
|
+
rb_define_attr(c_stream, "connection", 1, 0);
|
369
|
+
|
370
|
+
rb_define_const(c_stream, "NONBLOCK", INT2NUM(VIR_STREAM_NONBLOCK));
|
371
|
+
|
372
|
+
rb_define_const(c_stream, "EVENT_READABLE",
|
373
|
+
INT2NUM(VIR_STREAM_EVENT_READABLE));
|
374
|
+
rb_define_const(c_stream, "EVENT_WRITABLE",
|
375
|
+
INT2NUM(VIR_STREAM_EVENT_WRITABLE));
|
376
|
+
rb_define_const(c_stream, "EVENT_ERROR", INT2NUM(VIR_STREAM_EVENT_ERROR));
|
377
|
+
rb_define_const(c_stream, "EVENT_HANGUP", INT2NUM(VIR_STREAM_EVENT_HANGUP));
|
378
|
+
|
379
|
+
rb_define_method(c_stream, "send", libvirt_stream_send, 1);
|
380
|
+
rb_define_method(c_stream, "recv", libvirt_stream_recv, 2);
|
381
|
+
rb_define_method(c_stream, "sendall", libvirt_stream_sendall, -1);
|
382
|
+
rb_define_method(c_stream, "recvall", libvirt_stream_recvall, -1);
|
383
|
+
|
384
|
+
rb_define_method(c_stream, "event_add_callback",
|
385
|
+
libvirt_stream_event_add_callback, -1);
|
386
|
+
rb_define_method(c_stream, "event_update_callback",
|
387
|
+
libvirt_stream_event_update_callback, 1);
|
388
|
+
rb_define_method(c_stream, "event_remove_callback",
|
389
|
+
libvirt_stream_event_remove_callback, 0);
|
390
|
+
rb_define_method(c_stream, "finish", libvirt_stream_finish, 0);
|
391
|
+
rb_define_method(c_stream, "abort", libvirt_stream_abort, 0);
|
392
|
+
rb_define_method(c_stream, "free", libvirt_stream_free, 0);
|
393
|
+
#endif
|
394
|
+
}
|