Skip to main content

a silhouette of a person's head and shoulders, used as a default avatar

Kolab on its way back

After a long time, with lots of not visible activity Kolab, the groupware server build with many known open source components, is slowly getting back into openSUSE. For a year or so it was not possible to use Kolab on openSUSE versions newer than 10.3. That was due to the move from openldap 2.3 to 2.4. The latter does no longer support slurpd as replication mechanism, but uses syncrepl instead. Hence, kolab had to be extended to be able to work with new replication protocol. After that the way the webclient horde was packaged, changed from (to make a long story short) 1 big package, to many small packages. This in preparation for horde4. Today, the following message was posted to the kolab-user e-maillist:

after a lot of tests on a virtual system I finally upgraded my
productive Kolab server to 2.2.1 with the Suse packages.

Now you should now, that kolab-2.2.1 was released about month in April 2009. Although we (Marcus Huewe, Alar Sing, and the author of this article) are not there yet, seeing this message means a lot to us. We’re making good process!

a silhouette of a person's head and shoulders, used as a default avatar

Vacation / Trip report

Had 1.5 weeks of vacation to travel with 2 friends, a certain mouse, and various Fluffs to Denmark to visit a friend of theirs.

Friday (24th april): Roadtrip starting at 10:00 in Nuernberg ... We drove straight to Hamburg as the first days stop. Spent the evening at the Aussenalster, lounging at a jetty cafe and enjoying the setting sun over the water. Tried not to get run over by Joggers and Bikers. Hotel was a nice one in St Georg, except I could listen to everything happen in the neighbouring rooms and the staircase.

Saturday: Walked around the Binnenalster and the City. Met by chance my brother who lives in Hamburg. Met an old study friend of Edith and spent more time walking around and looking at St Pauli / Landungsbruecken, Ferries, Oevelgoenne and Blankenese. Then we drove on towards Luebeck. Luebeck was quieter and emptier then we imagined (or we did not really find the cool places). So Steakhouse first, and Irish Pub across the nice Hotel (Alter Speicher) later on.

Sunday: Visited the Guenter Grass House and the Figurenmuseum (funny enough, lots of hand puppets from all over the world ... but no Muppets (r).) ... Then drove on towards Denmark, where we spent the night in the even quieter costal town Fredericia.

Denmark smelled strongly of Guelle everywhere, farmers have been busy getting it to the fields apparently.

Monday: Drove on to visit Lindholm Hoje, a Viking grave site and after walking around it a bit, drove on the Ålbæk, near the northern most tip of Denmark. We had rented a vacation flat for 4 nights at a farmers place, quiet and nice. Lots of drinking and chatting.

Tuesday: Visited Skagen withs its art museum, and the tip of denmark in Grenen, where Skagerrak (Nordsee aka North Sea) and Kattegat (Ostsee aka Baltic Sea) meet each other, and the
a large aquarium in Hirthals.

Wednesday: A walk through the woods.

Thursday: More sightseeing around the area, visited to only left-as-is wandering dune Råbjerg Mile, various beaches on both the North and Baltic Sea. Enjoyed local fish in the evening.

Friday: Drove (mostly with a Ferry from Fredrikshaven) to Goeteborg. Spent the afternoon walking around in Goeteborg, drinking beer and watching the local girls who obviously are accustomed to walk around in shorts and tshirts at 10 degree celsius. Nice hotel called Vasa.

Saturday: Drove through south sweden and denmark to Gedser and then ferried over to Rostock. Found a nice hotel in Warnemuende and relaxed with beach walking and beer/wine.

Sunday: More refreshing beach walking, saying good by to the sea... Drove southwards, with a lunch stop in Potsdam to visit Sanssouci, then onwards back to Nuernberg.

Monday-Wednesday: Washing, helping Rasmus with his home network and getting barbeque as thanks, fixing libgphoto2...

Images are here.
the avatar of Sandy Armstrong

Tomboy 0.15.0 Development Release Brings New Features and Fixes, Even For 0.14.x Users!

I'm very pleased to announce Tomboy 0.15.0, our first development release on the road to Tomboy 1.0. A few of the improvements in 0.15.0 are:
  • New NoteDirectoryWatcher add-in supports editing of your note files in other programs (think Dropbox).
  • The first of many improvements to start-up time, by not rebuilding the add-in registry every time Tomboy starts. This also fixes start-up bugs on a few distributions, including Windows.
  • Random start-up crash in GConf fixed.
  • Many improvements to the printing add-in.
  • Better note and URL auto-linking.
  • Console output on Windows command prompts now works correctly, for better error reporting.

See our NEWS file for information on some usability improvements, better GMime support, Mono.Addins upgrade on Windows, and more.

Please visit our download page for source tarballs, Windows installers, and Mac disk images. Note that the Windows installer is still a work-in-progress, and for now you should always uninstall the previous version of Tomboy before installing a new one.

NoteDirectoryWatcher Add-in Available for 0.14.x Users on Linux, Windows, and Mac!

NoteDirectoryWatcher in Action

For years, users in various situations have tried setting up ad-hoc note synchronization solutions by syncing their ~/.tomboy directory between computers. This has never been supported, and because Tomboy would not notice outside changes to note files while it was running, could easily lead to data loss and confusion. Thanks to Mike Fletcher, we are one step closer to supporting this group of users. With this add-in enabled, if another process modifies your note files, Tomboy will notice the change and update appropriately (after a short delay).

The great thing about add-ins is that we can make this feature available for download to all of our 0.14.x users. Source is in git, but you can download this cross-platform binary, drop it in ~/.tomboy/addins/ , enable it in your preferences and try it out! As this is our first release of this feature, bugs are expected, so please report any problems you experience. :-)

Please remember that sharing your ~/.tomboy is still not recommended, because it contains a bunch of add-in metadata that should not be shared unless you have identical set-ups on each system. In an upcoming version of Tomboy, we will be getting rid of ~/.tomboy and following the FreeDesktop XDG specification, so note data and add-in configuration will be stored separately. If you care about our migration from ~/.tomboy to XDG directories, please read my proposal on the bug and leave your comments.

Upcoming Releases

"Droplet", Copyright Ellery Armstrong, Milk Teeth Photography, Used With Permission

Some of the fixes in 0.15.0 will be coming to our next 0.14.x maintenance release: 0.14.2. Expect news about this in a few days.

Our next development release, 0.15.1, should include some new features in note synchronization, better Windows support when multiple GTK+ apps are installed, and the typical assortment of fixes and improvements. We are planning to have a bug day soon where we'll milestone a lot of our outstanding bugs. I'll let you know when we have a date. :-)

Lastly, after the last Tomboy planning meeting, we developed a roadmap for our next stable release, which, pending a few specific improvements, will be versioned 1.0. I'll be writing more about this in the future, but for now, feel free to check it out, and if you are interested in helping, toss your name in there!

This post brought to you by the Tomboy Blogposter add-in.
a silhouette of a person's head and shoulders, used as a default avatar

Designing a RESTful api for YaST

As we move YaST to the Web, we also want to give it a web-like architecture offering its functionality for widespread consumption.

So we started off by separating the client frontend (user interface) from the server backend (functionality) and settling for a RESTful api between them. We also decided on using Ruby on Rails (usually just named 'Rails') to implement both layers. Besides its widespread adoption outside of OpenSUSE, Rails is used in a couple of company projects like

Rails comes as a natural choice as we can build upon a rich knowledge base with developers sitting (literally) next door. Rails was also one of the early adopters for RESTful and offers a nice encapsulation layer named ActiveResource.

ActiveResource ...

ActiveResource gives you an object-oriented interface for resources, hiding all the HTTP protocol or serialization issues from you.

Following the model-view-controller principle of Rails, resources are separated into their model, behaviour, and visualization. The resource model is expressed as a ruby class below app/models, the resource behaviour and basic lifecycle operations (create-read-update-delete) is implemented in a Controller class living below app/controllers, and app/views hosts the visualization files.

A device resource would be modelled as app/models/device.rb, implemented as app/controllers/devices_controller.rb, and viewed through app/views/devices. (Note that controllers are always plural, even for singleton resources.)

... and routing

To make resource accessible from the outside, routing information must be placed inside config/routes.rb. Routing assigns a URL to the resource, making it accessible from the outside and uniquely identifying it.

For the device resource, a map.resources :device call inside config/routes.rb would publish the resource as /devices, effectively offering a set of URLs and HTTP methods:

HTTP verb URL action used for
GET /devices index display a list of all devices
POST /devices create create a new device
GET /devices/1 show display a specific device
PUT /devices/1 update update a specific device
DELETE /devices/1 destroy delete a specific device
(taken from RailsGuides)

Limitations of the routing scheme

This scheme of identifying resources via URLs works well for a limited number of resources which all have models below app/models and controllers inside app/controllers.

But it is hard to follow if you allow resources as plugins, which you cannot control and prevent them stomping on another plugins feet. Imagine a printer plugin offering devices and a network plugin doing the same. The /devices URL cannot uniquely identify the resource, a simple

map.resources :devices
routing is not sufficient.

Pluggable resources

To make pluggable resources work, you have to centralize the routing and restrain from defining URLs. This also matches well with the RESTful principle of hypertext driven APIs and narrowing the URL exposure window.

A resource plugin for the rest-service of YaST is identified by the interface it offers and the controller implementing it.

This is done with a config file in yaml format. It specifies the interface and controller as

 interface: org.opensuse.yast.printer.devices
 controller: yast/printer/devices
in a .yml file below config/resources. A resource plugin can offer any number of resources this way.

Interfaces are qualified names like org.opensuse.yast.system.language or org.opensuse.yast.system.users. Ideally, these names should match the prefix for the PolicyKit action controlling access to the resource.

Implementation details

To minimize name clashes, the controller implementing the resource must be inside a namespace. Rails supports this by allowing subdirectories below app/controllers and automatically wrapping controller classes within modules matching the directory names.

Thus a network/device_controller and a printer/device_controller can live side-by-side an be accessed as Network::DeviceController and Printer::DeviceController. You could even nest more deeply like Org::Opensuse::Yast::System::Users, but let's not overdo it.

Rails resource routing puts another restriction on URLs: Rails manages routes as a set of maps, describing URLs as a combination of controller (implementing the resource) and action. Thus the file name and path of the controller define the URL, you cannot name them independently. So the controller: value in the resource description directly affects the resulting URL. Different resource plugins should use different namespaces to effectively prevent name clashes.

Querying the rest-service

The rest-service only publishes a single url, namely /resources, where clients can query for the URL offering a specific interface.

This URL follows RESTful principles since a HTTP GET request returns a list of all resources. Its also possible to request a specific output format, either by setting the Accept header of the http request or by appending .xml or .html.

You can easily try it out by starting the rest-service and pointing a browser to http://localhost:3000/resources.

To find the right resource URL, the client just needs to pass the interface name as ?interface=name and extract the reference from the result. Stay tuned for a future post exploring the client side in more detail.

a silhouette of a person's head and shoulders, used as a default avatar

MonoDevelop on Windows

Besides the efforts to make MonoDevelop play nice in MacOS X, we've also been doing progress in the Windows side. This is how it looks right now:



What you see above is MonoDevelop running on Windows Vista using Microsoft.NET. A lot of effort has gone into making it easy to build MonoDevelop. Mike Kestner has been working on an installer that provides the core libraries on which MD depends on (such as Mono.Addins), and I hope it will be soon available so that people can start using it. We've also fixed the MD project files, so now MD can be built by just opening the main solution in Visual Studio and clicking on build.

A new feature I had to add to MD in order to properly support Windows, is support for multiple runtimes. Thanks to that feature it is possible to select in the IDE which runtime you want to use for building and running a solution. It can be done using a combo box in the toolbar:


There is also a "Run With" menu which shows all runtimes, so you can run a specific project using a specific runtime. Notice that support for multiple runtimes is not specific to Windows, it is also supported in Linux. In this case, you can register several mono runtimes versions installed in different prefixes (I'll blog with more detail about that soon).

The basic funcitonality already works in Windows: loading a project, building running. Other features still don't work, such as the gtk# designer, the nunit add-in or the Subversion add-in. I haven't yet tried none of the add-ins in 'extras'.

I hope we'll be able to make a 2.2 release with a very decent Windows support. I'll keep posting and twittering updates.

a silhouette of a person's head and shoulders, used as a default avatar

openSUSE-GNOME BugDay!

Roll up those sleeves and mark your calendars, because here comes another BugDay!

During Community Week (http://en.opensuse.org/CommunityWeek), I’ll be hosting another openSUSE-GNOME BugDay on Fri, 15 MAY 2009. We’ll start promptly at 1000 CDT and will continue until 1600 CDT. I will be around very early in the day to start prep for the meeting should you have any questions.

We’ll conduct business in #opensuse-gnome on Freenode (irc.freenode.net). I will establish a Gobby session as I’ve done in the past, and we’ll work off of that.

Can’t wait to see you there!

the avatar of Katarina Machalkova

Secret AutoYaST feature :)

Recently I've discovered a secret feature in AutoYaST. Well, probably not so secret, because a SLES11 user (from our Two-Letter Customer) discovered it as well and reported a bug about it :) But all in all, if you googled for the keyword (keep_install_network) a week ago, the only hits were an AutoYaST changelog with short notice "I've added this feature" and few questions about it on opensuse-autoinstall mailing list. The documentation did not reveal any more details.

So - what does keep_install_network parameter, set to 'true' and inserted into <networking> section of AutoYaST profile, do? One can intuitively guess that it will preserve network configuration - that is, interfaces setup, resolv.conf bits, static routing, udev rules & co. - from 1st stage of installation (of course, only if the installation actually runs over the network) and it is indeed like that. Uwe blogs about it in more details

But unless you use openSUSE Factory, please don't try this at home :)

<networking>
  <keep_install_network config:type="boolean">true</keep_install_network>
</networking>
Network interfaces setup (ifcfg files) from the installation will be successfully preserved, but due to a bug, your static routing configuration (if you have any) will be moved into backup file and YaST won't create a new one and you will lose most of the information in /etc/resolv.conf. Unfortunately, nobody got the idea to test with the profile containing nothing more but keep_install_network entry in networking section so far :(

The bug is fixed now for openSUSE 11.2 and SLE11 SP1 (if nothing in particular sub-section of networking section is defined, the setup from installation is used, but AutoYaST profile is the higher authority here). However, if you use SLE11, you'd better install with profile containing at least minimal DNS and routing info, for example like this (set search domain, 1 nameserver and default gateway):

<networking>
    <keep_install_network config:type="boolean">true</keep_install_network>
    <dns>
      <dhcp_hostname config:type="boolean">false</dhcp_hostname>
      <domain>home.net</domain>
      <hostname>dolphin</hostname>
      <nameservers config:type="list"> 
        <nameserver>192.168.0.2</nameserver>
      </nameservers>
      <searchlist config:type="list">
        <search>home.net</search>
      </searchlist>
    </dns>
    <routing>
      <ip_forward config:type="boolean">false</ip_forward>
      <routes config:type="list">
        <route>
          <destination>default</destination>
          <device>-</device>
          <gateway>192.168.0.1</gateway>
          <netmask>-</netmask>
        </route>
      </routes>
    </routing>
  </networking>
Or use a workaround post-script Uwe posted to bugzilla, to backup your setup and to restore it later.

One good thing about these bugs is that not only it broadens your knowledge (when user comes up with scenario you never thought of) ;-) but it also helps us to improve things. keep_install_network feature is now documented and not secret anymore. Enjoy it!

a silhouette of a person's head and shoulders, used as a default avatar

GSoC introduction – openSUSE@ARM

Hi openSUSE community!

I’m glad my proposal was accepted and today I want to introduce myself and my GSoC project.

/me , thats Jan-Simon Möller and I’m just finishing my Diploma in electrical engineering at the Leibniz Universität Hannover. I’m coordinator of the openSUSE Weekly Newsletter and contribute also to the hamradio repository, the iFolder project and the openSUSE Build Service. See also my “People of openSUSE” interview.

My Project in short:  openSUSE@ARM
My aim during GSoC 2009 is to port first the base to the ARM platform. Then KIWI needs also some attention when it comes to imaging and after that the tools, Kernel and X11.

I’ll heavily use the capabilities of the openSUSE Build Service, which is now ready for ARM.

During the last few days, I’ve done many little preparations to get it all flying when GSoC coding period starts.

Stay tuned !

a silhouette of a person's head and shoulders, used as a default avatar

Suppressing KeyboardInterrupt traceback in Python

If you have a running program in Python and press Ctrl+C, you’ll get a traceback like this:

$ scout java foo
^CTraceback (most recent call last):
  File "/usr/bin/scout", line 11, in 
    ret = scout.ScoutCore.run()
  File "/usr/lib64/python2.6/site-packages/scout/__init__.py", line 945, in run
    result = module.ScoutModule().main(clp.module_args)
  File "/usr/lib64/python2.6/site-packages/scout/__init__.py", line 873, in main
    return self.do_query(args.query, repos, args.inversesearch)
  File "/usr/lib64/python2.6/site-packages/scout/__init__.py", line 890, in do_query
    result.add_rows(self._query(repo, query, inversesearch))
  File "/usr/lib64/python2.6/site-packages/scout/__init__.py", line 896, in _query
    r = db.query(self._sql, '%%%s%%' % term)
  File "/usr/lib64/python2.6/site-packages/scout/__init__.py", line 485, in query
    if len(row) == 1:           #(2)
KeyboardInterrupt

It is useful suppress it, because user knows he breaks the program and this output should be considered as a bug. Possible solution is wrap a main function by one big try: except KeyboardInterrupt:

try:
  main() # the main function
except KeyboardInterrupt:
  pass # KeyboardInterrupt supressed

But it makes a new level of indentation which should be uncomfortable – especially in Python. Or when you have multiple entry-points, or just don’t well structured program (which is common when you write your private helper script :)), you maybe prefer another solution.

Python has a sys.excepthook, which is called for traceback printing, so we could define our own and suppress unnecessary output here. And it would be nice suppress only one exception and handle other ones using existing function. And this function make it:

def suppress_keyboard_interrupt_message():
    old_excepthook = sys.excepthook

    def new_hook(type, value, traceback):
        if type != exceptions.KeyboardInterrupt:
            old_excepthook(type, value, traceback)
        else:
            pass

    sys.excepthook = new_hook

Function suppress_keyboard_interrupt_message (it is really nice name, don’t it ;-)) stores an existing hook and register an inner function new_hook as a new one. Advantage is that old_excepthook exists only in a scope of this function, so you don’t need use global variables for it.

Update: typos fixed

a silhouette of a person's head and shoulders, used as a default avatar