Code Sample for Event Lis

Discussion about using the VirtualBox API, Tutorials, Samples.
Post Reply
neubert
Posts: 9
Joined: 10. Aug 2008, 10:57

Code Sample for Event Lis

Post by neubert »

Dear all,

I have integrated my virtualbox virtual machine park into my home automation dashboard by means of SSHed VBoxManage scripts - quite baroque code. Want to replace this by a neat module based on the virtualbox API.

Progamming language is Perl. First success with Perl example code in the SDK and retrieving information about the host. Now want to listen to some events (start, pause, save, reset, ...) from virtual machines by means of Event Aggregator. Looks like a steep learning curve to rephrase the examples and method pool from the SDK docs to work in Perl.

Searched the web for quite long but was unable to locate Perl code snippets to learn by example. Looks like Perl is rarely used for accessing virtualbox API.

Please can anybody throw some links, book reference, code samples at me?

Best regards,
Boris
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Code Sample for Event Lis

Post by noteirak »

I personally code in Java, so I could give you a full Java example, or pseudo code using the interface names in the SDK. Would that help?
The sample will also depend on what you want to listen for, so please tell me exactly - you can see here for a full list of the event classes and a full list of event types, both with description and some explaination.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
neubert
Posts: 9
Joined: 10. Aug 2008, 10:57

Re: Code Sample for Event Lis

Post by neubert »

Thank you, noteirak.

I think I will be able to translate the Java example into perl and pseudo code will do maybe even better for me. I use Perl with SOAP::Simple on Debian 7.8 (Raspian) for remote access to the API of virtualbox on CentOS 6.6 - that means that I cannot benefit from an object-oriented approach and have to call the methods with the interface_method naming approach. That was an additional hurdle to me.

I checked the event types and I need to collect and maintain information about the current state of the VMs:
  • VBoxEventType_OnMachineStateChanged for all registered VMs at once
  • VBoxEventType_OnRuntimeError
In addition, I want to be able to start commands within the VMs with IGuestSession::processCreate and be informed on their status:
  • VBoxEventType_OnGuestProcessStateChanged


Some background: I am a co-developer of the free open-source home automation system FHEM. Due to its outstanding flexibility, the software has evolved into a swiss army knive for virtually any automation needs in the home, with a community of ~10,000 users in the forum. I will develop a module with a "host device" representing the virtualbox host and many "machine devices" representing the VMs. Devices have "readings" (here: VM state) and can be "set" (turn on, off, ..., execute command). The purpose is primarily a rudimentary dashboard (far simpler than phpvirtualbox) in the FHEM web interface and the possibility to automate some actions (e.g. create a database dump for later backup before saving the state of the virtualized database server).

Kind regards
Boris
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Code Sample for Event Lis

Post by noteirak »

Ok so the logic is the same if you want a machine state change event or the guest process event, you simply use a different even source reference. For the OnRuntimeError event, I am not sure which one will produce it, so try on both.

For the Machine state, you will use the IVirtualBox object event source out of the box. For the Guest Process, you'll use IGuestProcess, and you'll need to have a Shared lock on the machine, usually the one that you obtained to get the guest process.
In both case, I assume you have already connected to VirtualBox using the relevant connection logic for each binding.

Machine state :

Code: Select all

IEventSource es = IVirtualBox::getEventSource()
IEventListener el = es.createListener()
es.registerListener(el, Array[VBoxEventType.OnMachineStateChanged], false) // we need to provide an array of event type we want to listen for, in this case only machine state changed, and false to set the event handling to passive
try { // we need to prevent against any exception or related things so we can clean
	while (your exit condition) { // This is where we fetch events. We must keep getting them to avoid system overload
		IEvent rawEvent = es.getEvent(el, 1000) // 2nd argument is a wait timeout, 1000ms in this case
		if (rawEvent != null) { // if no event was found in the timeout period, we get null. else we continue
			try { // we prevent against exception to perform event process clean up
				if (rawEvent.getType() == VBoxEventType::OnMachineStateChanged) { // sanity check, required when you register for several events. This tends to become a switch statement or some kind of factory call
					IMachineStateChangedEvent event = IMachineStateChangedEvent::queryInterface(rawEvent) // we turn our raw event into the precise event so we can access relevant methods
					MachineState machineState = event.getState()
					// do stuff
				}
				if (rawEvent.getType() == something else) { // if we added more events to the Array given to IEventSource::registerListener()
					// do some other stuff
				}
			} finally { // clean up
				es.eventProcessed(el, ev) // we must mark the event as processed
			}
		}
	}
} finally { // clean up
	es.unregisterListener(el)
}
For the guest process, it's the exact same logic except that instead of getting your IEventSource on IVirtualBox, you get it on your IGuestProcess object.
In case you use a different thread for the event listener (most likely case), make sure you get a dedicated session using LockType.Shared to listen on IGuestProcess events.
If you use the same session object than in your main thread and that thread close the session, your event thread will fail.

PS: nice project :)
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
neubert
Posts: 9
Joined: 10. Aug 2008, 10:57

Re: Code Sample for Event Listener

Post by neubert »

Thank you for the code and the recommendations.

Since the project is not multithreaded, that code will run this in a separate child process and communicate with the main program via pipe.

Will take some time now to complete...

Thanks again
Boris
Post Reply