Module: Libvirt

Defined in:
lib/libvirt.rb,
ext/libvirt/_libvirt.c

Defined Under Namespace

Classes: ConnectionError, DefinitionError, Error, Interface, NWFilter, NoSupportError, NodeDevice, RetrieveError, Version

Constant Summary collapse

CONNECT_RO =
INT2NUM(VIR_CONNECT_RO)
CRED_USERNAME =
INT2NUM(VIR_CRED_USERNAME)
CRED_AUTHNAME =
INT2NUM(VIR_CRED_AUTHNAME)
CRED_LANGUAGE =
INT2NUM(VIR_CRED_LANGUAGE)
CRED_CNONCE =
INT2NUM(VIR_CRED_CNONCE)
CRED_PASSPHRASE =
INT2NUM(VIR_CRED_PASSPHRASE)
CRED_ECHOPROMPT =
INT2NUM(VIR_CRED_ECHOPROMPT)
CRED_NOECHOPROMPT =
INT2NUM(VIR_CRED_NOECHOPROMPT)
CRED_REALM =
INT2NUM(VIR_CRED_REALM)
CRED_EXTERNAL =
INT2NUM(VIR_CRED_EXTERNAL)
EVENT_HANDLE_READABLE =
INT2NUM(VIR_EVENT_HANDLE_READABLE)
EVENT_HANDLE_WRITABLE =
INT2NUM(VIR_EVENT_HANDLE_WRITABLE)
EVENT_HANDLE_ERROR =
INT2NUM(VIR_EVENT_HANDLE_ERROR)
EVENT_HANDLE_HANGUP =
INT2NUM(VIR_EVENT_HANDLE_HANGUP)

Class Method Summary collapse

Class Method Details

.Libvirt::event_invoke_handle_callback(handle, fd, events, opaque) ⇒ Qnil

Unlike most of the other functions in the ruby-libvirt bindings, this one does not directly correspond to a libvirt API function. Instead, this module method (and event_invoke_timeout_callback) are meant to be called when there is an event of interest to libvirt on one of the file descriptors that libvirt uses. The application is notified of the file descriptors that libvirt uses via the callbacks from Libvirt::event_register_impl. When there is an event of interest, the application must call event_invoke_timeout_callback to ensure proper operation.

Libvirt::event_invoke_handle_callback takes 4 arguments:

handle

an application specific handle ID.  This can be any integer, but
must be unique from all other libvirt handles in the application.

fd

the file descriptor of interest.  This was given to the application
as a callback to add_handle of Libvirt::event_register_impl

events

the events that have occured on the fd.  Note that the events are
libvirt specific, and are some combination of
Libvirt::EVENT_HANDLE_READABLE, Libvirt::EVENT_HANDLE_WRITABLE,
Libvirt::EVENT_HANDLE_ERROR, Libvirt::EVENT_HANDLE_HANGUP.  To
notify libvirt of more than one event at a time, these values should
be logically OR'ed together.

opaque

the opaque data passed from libvirt during the
Libvirt::event_register_impl add_handle callback.  To ensure proper
operation this data must be passed through to
event_invoke_handle_callback without modification.

Returns:

  • (Qnil)


359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'ext/libvirt/_libvirt.c', line 359

static VALUE libvirt_event_invoke_handle_callback(VALUE m, VALUE handle,
                                                  VALUE fd, VALUE events,
                                                  VALUE opaque) {
    virEventHandleCallback cb;
    void *op;
    VALUE libvirt_cb;
    VALUE libvirt_opaque;

    if (TYPE(opaque) != T_HASH)
        rb_raise(rb_eTypeError,
                 "wrong event callback argument type (expected Hash)");

    libvirt_cb = rb_hash_aref(opaque, rb_str_new2("libvirt_cb"));

    /* This is equivalent to Data_Get_Struct; I reproduce it here because
     * I don't want the additional type-cast that Data_Get_Struct does
     */
    Check_Type(libvirt_cb, T_DATA);
    cb = DATA_PTR(libvirt_cb);

    if (cb) {
        libvirt_opaque = rb_hash_aref(opaque, rb_str_new2("opaque"));
        Data_Get_Struct(libvirt_opaque, void *, op);
        cb(NUM2INT(handle), NUM2INT(fd), NUM2INT(events), op);
    }

    return Qnil;
}

.Libvirt::event_invoke_timeout_callback(timer, opaque) ⇒ Qnil

Unlike most of the other functions in the ruby-libvirt bindings, this one does not directly correspond to a libvirt API function. Instead, this module method (and event_invoke_handle_callback) are meant to be called when there is a timeout of interest to libvirt. The application is notified of the timers that libvirt uses via the callbacks from Libvirt::event_register_impl. When a timeout expires, the application must call event_invoke_timeout_callback to ensure proper operation.

Libvirt::event_invoke_timeout_callback takes 2 arguments:

handle

an application specific timer ID.  This can be any integer, but
must be unique from all other libvirt timers in the application.

opaque

the opaque data passed from libvirt during the
Libvirt::event_register_impl add_handle callback.  To ensure proper
operation this data must be passed through to
event_invoke_handle_callback without modification.

Returns:

  • (Qnil)


411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'ext/libvirt/_libvirt.c', line 411

static VALUE libvirt_event_invoke_timeout_callback(VALUE m, VALUE timer,
                                                   VALUE opaque) {
    virEventTimeoutCallback cb;
    void *op;
    VALUE libvirt_cb;
    VALUE libvirt_opaque;

    if (TYPE(opaque) != T_HASH)
        rb_raise(rb_eTypeError,
                 "wrong event callback argument type (expected Hash)");

    libvirt_cb = rb_hash_aref(opaque, rb_str_new2("libvirt_cb"));

    /* This is equivalent to Data_Get_Struct; I reproduce it here because
     * I don't want the additional type-cast that Data_Get_Struct does
     */
    Check_Type(libvirt_cb, T_DATA);
    cb = DATA_PTR(libvirt_cb);

    if (cb) {
        libvirt_opaque = rb_hash_aref(opaque, rb_str_new2("opaque"));
        Data_Get_Struct(libvirt_opaque, void *, op);
        cb(NUM2INT(timer), op);
    }

    return Qnil;
}

.Libvirt::event_register_impl(add_handle = nil, update_handle = nil, remove_handle = nil, add_timeout = nil, update_timeout = nil, remove_timeout = nil) ⇒ Qnil

Call virEventRegisterImpl[http://www.libvirt.org/html/libvirt-libvirt.html#virEventRegisterImpl] to register callback handlers for handles and timeouts. These handles and timeouts are used as part of the libvirt infrastructure for generating domain events. Each callback must be a Symbol (that is the name of a method to callback), a Proc, or nil (to disable the callback). In the end-user application program, these callbacks are typically used to track the file descriptors or timers that libvirt is interested in (and is intended to be integrated into the “main loop” of a UI program). The individual callbacks will be given a certain number of arguments, and must return certain values. Those arguments and return types are:

add_handle(fd, events, opaque) => Fixnum

update_handle(handleID, event) => nil

remove_handle(handleID) => opaque data from add_handle

add_timeout(interval, opaque) => Fixnum

update_timeout(timerID, timeout) => nil

remove_timeout(timerID) => opaque data from add_timeout

Any arguments marked as “opaque” must be accepted from the library and saved without modification. The values passed to the callbacks are meant to be passed to the event_invoke_handle_callback and event_invoke_timeout_callback module methods; see the documentation for those methods for more details.

Returns:

  • (Qnil)


655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
# File 'ext/libvirt/_libvirt.c', line 655

static VALUE libvirt_conn_event_register_impl(int argc, VALUE *argv, VALUE c) {
    virEventAddHandleFunc add_handle_temp;
    virEventUpdateHandleFunc update_handle_temp;
    virEventRemoveHandleFunc remove_handle_temp;
    virEventAddTimeoutFunc add_timeout_temp;
    virEventUpdateTimeoutFunc update_timeout_temp;
    virEventRemoveTimeoutFunc remove_timeout_temp;

    /*
     * subtle; we put the arguments (callbacks) directly into the global
     * add_handle, update_handle, etc. variables.  Then we register the
     * internal functions as the callbacks with virEventRegisterImpl
     */
    rb_scan_args(argc, argv, "06", &add_handle, &update_handle, &remove_handle,
                 &add_timeout, &update_timeout, &remove_timeout);

    if (!is_symbol_proc_or_nil(add_handle) ||
        !is_symbol_proc_or_nil(update_handle) ||
        !is_symbol_proc_or_nil(remove_handle) ||
        !is_symbol_proc_or_nil(add_timeout) ||
        !is_symbol_proc_or_nil(update_timeout) ||
        !is_symbol_proc_or_nil(remove_timeout))
        rb_raise(rb_eTypeError,
                 "wrong argument type (expected Symbol, Proc, or nil)");

    set_event_func_or_null(add_handle);
    set_event_func_or_null(update_handle);
    set_event_func_or_null(remove_handle);
    set_event_func_or_null(add_timeout);
    set_event_func_or_null(update_timeout);
    set_event_func_or_null(remove_timeout);

    /* virEventRegisterImpl returns void, so no error checking here */
    virEventRegisterImpl(add_handle_temp, update_handle_temp,
                         remove_handle_temp, add_timeout_temp,
                         update_timeout_temp, remove_timeout_temp);

    return Qnil;
}

.Libvirt::open(uri = nil) ⇒ Libvirt::Connect

Call virConnectOpen[http://www.libvirt.org/html/libvirt-libvirt.html#virConnectOpen] to open a connection to a URL.

Returns:

  • (Libvirt::Connect)


113
114
115
# File 'ext/libvirt/_libvirt.c', line 113

static VALUE libvirt_open(int argc, VALUE *argv, VALUE m) {
    return internal_open(argc, argv, m, 0);
}

.Libvirt::open_auth(uri = nil, credlist = nil, userdata = nil, flags = 0) {|...| ... } ⇒ Libvirt::Connect

Call virConnectOpenAuth[http://www.libvirt.org/html/libvirt-libvirt.html#virConnectOpenAuth] to open a connection to a libvirt URI, with a possible authentication block. If an authentication block is desired, then credlist should be an array that specifies which credentials the authentication block is willing to support; the full list is available at libvirt.org/html/libvirt-libvirt.html#virConnectCredentialType. If userdata is not nil and an authentication block is given, userdata will be passed unaltered into the authentication block. The flags parameter controls how to open connection. The only options currently available for flags are 0 for a read/write connection and Libvirt::CONNECT_RO for a read-only connection.

If the credlist is not empty, and an authentication block is given, the authentication block will be called once for each credential necessary to complete the authentication. The authentication block will be passed a single parameter, which is a hash of values containing information necessary to complete authentication. This hash contains 5 elements:

type - the type of credential to be examined

prompt - a suggested prompt to show to the user

challenge - any additional challenge information

defresult - a default result to use if credentials could not be obtained

userdata - the userdata passed into open_auth initially

The authentication block should return the result of collecting the information; these results will then be sent to libvirt for authentication.

Yields:

  • (...)

Returns:

  • (Libvirt::Connect)


227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'ext/libvirt/_libvirt.c', line 227

static VALUE libvirt_open_auth(int argc, VALUE *argv, VALUE m) {
    virConnectAuthPtr auth;
    VALUE uri;
    VALUE credlist;
    VALUE userdata;
    VALUE flags_val;
    char *uri_c;
    virConnectPtr conn = NULL;
    unsigned int flags;
    int auth_alloc;
    int i;
    VALUE tmp;
    int exception = 0;
    struct rb_ary_entry_arg args;
    struct wrap_callout callargs;

    rb_scan_args(argc, argv, "04", &uri, &credlist, &userdata, &flags_val);

    /* handle the optional URI */
    uri_c = get_string_or_nil(uri);

    /* handle the optional flags */
    if (NIL_P(flags_val))
        flags = 0;
    else
        flags = NUM2UINT(flags_val);

    if (rb_block_given_p()) {
        auth = ALLOC(virConnectAuth);
        auth_alloc = 1;

        if (TYPE(credlist) == T_NIL)
            auth->ncredtype = 0;
        else if (TYPE(credlist) == T_ARRAY)
            auth->ncredtype = RARRAY_LEN(credlist);
        else
            rb_raise(rb_eTypeError, "wrong argument type (expected Array or nil)");
        auth->credtype = NULL;
        if (auth->ncredtype > 0) {
            /* we don't use ALLOC_N here because that can throw an exception,
             * and leak the auth pointer.  Instead we use normal malloc
             * (which has a slightly higher chance of returning NULL), and
             * then properly cleanup if it fails
             */
            auth->credtype = malloc(sizeof(int) * auth->ncredtype);
            if (auth->credtype == NULL) {
                xfree(auth);
                rb_memerror();
            }
            for (i = 0; i < auth->ncredtype; i++) {
                args.arr = credlist;
                args.elem = i;
                tmp = rb_protect(rb_ary_entry_wrap, (VALUE)&args, &exception);
                if (exception)
                    goto do_cleanup;

                auth->credtype[i] = rb_protect(rb_num2int_wrap, tmp,
                                               &exception);
                if (exception)
                    goto do_cleanup;
            }
        }

        auth->cb = libvirt_auth_callback_wrapper;
        auth->cbdata = (void *)userdata;
    }
    else {
        auth = virConnectAuthPtrDefault;
        auth_alloc = 0;
    }

    callargs.uri = uri_c;
    callargs.auth = auth;
    callargs.flags = flags;

    conn = (virConnectPtr)rb_protect(rb_open_auth_wrap, (VALUE)&callargs,
                                     &exception);

do_cleanup:
    if (auth_alloc) {
        free(auth->credtype);
        xfree(auth);
    }

    if (exception)
        rb_jump_tag(exception);

    _E(conn == NULL, create_error(e_ConnectionError, "virConnectOpenAuth",
                                  NULL));

    return connect_new(conn);
}

.Libvirt::open_read_only(uri = nil) ⇒ Libvirt::Connect

Call virConnectOpenReadOnly[http://www.libvirt.org/html/libvirt-libvirt.html#virConnectOpenReadOnly] to open a read-only connection to a URL.

Returns:

  • (Libvirt::Connect)


125
126
127
# File 'ext/libvirt/_libvirt.c', line 125

static VALUE libvirt_open_read_only(int argc, VALUE *argv, VALUE m) {
    return internal_open(argc, argv, m, 1);
}

.Libvirt::version(type = nil) ⇒ Array

Call virGetVersion[http://www.libvirt.org/html/libvirt-libvirt.html#virGetVersion] to get the version of libvirt and of the hypervisor TYPE.

Returns:

  • (Array)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'ext/libvirt/_libvirt.c', line 61

static VALUE libvirt_version(int argc, VALUE *argv, VALUE m) {
    unsigned long libVer;
    VALUE type;
    unsigned long typeVer;
    int r;
    VALUE result, rargv[2];

    rb_scan_args(argc, argv, "01", &type);

    r = virGetVersion(&libVer, get_string_or_nil(type), &typeVer);
    _E(r < 0, create_error(rb_eArgError, "virGetVersion", NULL));

    result = rb_ary_new2(2);
    rargv[0] = rb_str_new2("libvirt");
    rargv[1] = ULONG2NUM(libVer);
    rb_ary_push(result, rb_class_new_instance(2, rargv, c_libvirt_version));
    rargv[0] = type;
    rargv[1] = ULONG2NUM(typeVer);
    rb_ary_push(result, rb_class_new_instance(2, rargv, c_libvirt_version));
    return result;
}