Friday, November 28, 2008

Libvirt 0.5.0

This may be old news for some but libvirt 0.5.0 is now available. As usual, the bug fixes and improvements are spread throughout the library. There looks to be some interesting new features in the Qemu/KVM driver. Namely, "domain lifecycle event support" and "migration support".

The domain life cycle support includes Python bindings according to the change log whereas nothing is mentioned about Python support regarding the migration support for Qemu/KVM. Also, the domain life cycle support mentions only Qemu and Xen. I haven't actually tried using 0.5.0 yet but if I find anything else interesting to write about I will.

Thursday, November 27, 2008

An interface/generalization design pattern

Interfaces are useful for specifying a contract that one or many classes may realize. Generalization is useful for a similar purpose. If class A is inherited by class B, all the structural and behavioral features of class A because features of class B. In effect, class B realizes the interface of class A.

A good software development practice would then be to create a base class for each interface in your application that realizes each interface respectively. This way, any subsequent classes that are implemented can realize interfaces in your application in one of two ways. The first, directly realize the interface using the programming language constructs. The second, generalize the base class that corresponds to the interface you wish to realize.

By creating a base class for each interface that is ready to use by subclasses, you can implement some of the simpler methods in the base class. Subclasses may then only need to implement one or a few methods while still indirectly realizing the interface. One can argue that the interface level can be cut out completely. You could. The interface simply serves as an abstract conceptual tool for developers. You could only use generalization and override methods as needed. Both ways are valuable object oriented design but I think you'll find combining generalization and interfaces much more flexible and fun.

Wednesday, November 26, 2008

Enomaly ECP update

Just this week, I've started writing some new unit tests for Enomaly ECP. I decided to take a different approach than the previous unit tests. These new tests are designed to test the RESTful API of the software. The new testing module, which I'm using to test version 2.2, establishes a connection with a running ECP instance and makes several HTTP requests to the API. The results for each test pass or fail based on the HTTP status, the internal error code returned, and ensuring that modifications actually took place.

Another nice little tool I've incorporated into the new unit testing is sptest. It gives us some nice colourful output.

This shift in testing focus will hopefully yield a more robust API for the Enomaly ECP platform that can be verified with test results. I hope to actually ship this new testing module with 2.2 so users can run the unit tests for themselves.

Tuesday, November 25, 2008

Python libvirt example

Xen sucks for my purposes. Xen is an extremely powerful virtualization platform and is why I don't need it. Few people do for development or experimental purposes. This is where KVM, QEMU, and Libvirt come in handy. I can use Python to easily write a simple application to create virtual machines and manipulate them as needed using the Libvirt Python binding. So, here is a simple example of how to get started using Libvirt in Python.
#Simple Python libvirt example.

import libvirt

if __name__=='__main__':
conn=libvirt.open('qemu:///system')
print 'Listing running domains'
for id in conn.listDomainsID():
dom=conn.lookupByID(id)
print dir(dom)

print 'Listing defined domains'
for id in conn.listDefinedDomains():
dom=conn.lookupByName(id)
print dir(dom)
The great thing about Libvirt is that, in theory, should decide I want to use Xen, this same code should work. Libvirt is still in its' infancy with a long way to go but the ideas are right.

Monday, November 24, 2008

Interfaces in Gaphor

I wrote earlier about Python interfaces and the Gaphor UML modeling tool demonstrates the use of Python interfaces quite nicely. Here, we show the interfaces that several classes in Gaphor implement. What is notable here is the simplistic design. There is not an entire plethora of interfaces to choose from. Only those that are important for accomplishing the applications' goals.

Thursday, November 6, 2008

Umbrello on Ubuntu 8.10

Shortly after updating my Ubuntu system to 8.10, I got an update for Umbrello, the UML diagramming tool. So far, I'm very impressed. The application is essentially the same but it actually works with KDE 4. Here is a screen shot.



So, I suppose I'm not excited about Umbrello itself. Just the fact that it works with KDE 4. I never thought I'd say it but KDE 4 has impressed me thus far.

Wednesday, November 5, 2008

Enomaly ECP update

I've started the enormous task of completely replacing the dialog widgets in ECP 2.2. I've decided that the current implementation doesn't really fit the jQuery architecture and that dialogs aren't all that pretty to look at. ECP 2.2 will use the ui.dialog jQuery plugin. It offers much more flexibility than the current dialog and looks better too. Here is a preview of what the dialogs will look like in ECP 2.2.



The finished product may not look exactly like this. There may be some finishing style touches before the final release. Either way, it is proving to be a nice visual enhancement.

Tuesday, November 4, 2008

Some TurboGears configuration thoughts

The TurboGears Python web framework uses Cherrypy as the web server. Cherrypy offers several other useful features other than strictly "web server" functionality. One of these features is project configuration. TurboGears basically builds on the Cherrypy configuration functionality. TurboGears also uses a Python package called ConfigObj to help distribute responsibilities. If there is one thing the TurboGears project does well, it would have to be reusing existing functionality rather than rebuild it.

When retrieving a configuration value in a TurboGears project using get(), TurboGears simply uses the Cherrypy configuration. However, the TurboGears framework is responsible for keeping the Cherrypy configuration component up to date. For example, lets say you need to update the project configuration dynamically as the result of some client request. This can be done is one of two ways. The first, you could pass a key/value dictionary to update(). The second, you could pass a configuration file to update_config(). In both cases, we are essentially updating the Cherrypy configuration. The ConfigObj package comes in handy when we need to read configuration files. Not when we already have a key/value configuration dictionary.

My main criticism of the TurboGears config module is that I wish there were a factory function that simply generated a configuration instance. This instance would be a representation of the configuration for the entire project. All the functions that are currently defined in the TurboGears config module could be instance methods of this new configuration class. I haven't yet looked in the trunk yet to see whats happening there with the config module.

Monday, November 3, 2008

Enomaly ECP update

First things first. ECP 2.1.1, which is a minor maintenance release, will hopefully be released this week. This release only contains bug fixes and minimal interface enhancements.

On the ECP 2.2 front, there have been lots of enhancements made in the configuration core module. The main change here is the addition of several classes that provide managed python attributes. These classes are also instantiated by the configuration module. Each managed attribute has the ability to either retrieve or store a configuration value depending on how the attribute is used. Under the covers, the attributes use Variable.load() and Variable.save(). So far, this implementation has fitted nicely into the code where configuration values are needed.

The code looks much cleaner with simple dot notation as opposed to several Variable.load() calls.