ruby-libvirt 0.3.0 → 0.4.0
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.
- 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
|
+
}
|