Thursday, March 12, 2009

Satsolver bindings documentation available

One of the outstanding features of openSUSE is the Sat solver for package dependency resolution.

Somewhat unknown to most developers, Satsolver provides bindings for the three major scripting languages: Perl, Python and Ruby. The bindings provide an easy way to learn about the Satsolver API, to explore package metadata and play what-if scenarios installing, updating and deleting packages.

The bindings are created using SWIG together with an application layer on top of the raw libsatsolver. The focus is on usability and support of the scripting language, while hiding internals of the Satsolver implementation.

The bindings documentation are hosted at http://www.suse.de/~kkaempf/satsolver-bindings-ruby for now. I hope to find a permanent place at opensuse.org in the future.

The documentation is created using rdoc with a SWIG specific parser. rdoc comes with Ruby, just install the ruby package for the rdoc framework. The swig parser is currently hosted inside the Satsolver git repo.

Although based on a Ruby specific tool, the use of SWIG ensures portability across languages. Example uses of the bindings are available for Perl, Python and Ruby If you need Satsolver bindings for other languages, drop the ZYpp developers a mail.

Monday, March 09, 2009

D-Bus service on demand

Here is the last part of my mini-series about D-Bus, this time on D-Bus activation

In my last blog entry I talked about implementing a D-Bus service in Ruby. Running the service was done as a background daemon, started by root (or with other credentials).

D-Bus also provides an on-demand service creation, named activation. Here the D-Bus daemon creates the service as soon as a client is requesting it. Shutdown of the service is at the discretion of the implementation, the D-Bus deamon does not automatically deactivate a running service.

About D-Bus activation

For D-Bus actication, you have to create a .service file. This is an INI-style format file containing

  • the name of the service
  • the file to run, implementing the service
  • the user name to run the service as

Since the D-Bus daemon runs as user 'messagebus' and thus is unprivileged. It cannot directly run the service or assume the correct user credentials.

Instead, it uses a service helper which is setuid root to start the service. This helper is configured within /etc/dbus-1/system.conf as <servicehelper> and typically resides below /lib/dbus-1/dbus-daemon-launch-helper (/lib64/dbus-1/dbus-daemon-launch-helper on 64bit systems).

dbus-daemon-launch-helper is extra-picky when it comes to security and checks its own configuration at startup. If your D-Bus service fails to get activated, maybe dbus-daemon-launch-helper is not correctly installed.

Writing the .service file

The name of the service file must be equal to the service name with a .service extension.

A typical service file for my.awesome.Service would be named my.awesome.Service.service and contain

# DBus service activation config
[D-BUS Service]
Name=my.awesome.Service
Exec=/usr/bin/awesome
User=the_dude

Name is the name of the service, Exec the path to the executable implementing the service and User the user name to run the service. Be careful when using User=root, only very few services actually need root rights.

The Exec line can also contain arguments to be passed to the executable. This can be used to e.g. implement multiple services in a single binary and pass the actual service name as a parameter.

Installing the .service file

Just copy the service file to either /usr/share/dbus-1/system-services (for a system bus service) or to /usr/share/dbus-1/services (for a session bus service).

Your service is now ready to run. The D-Bus daemon will automatically pick up changes in the service directories and find the new file.