Skip to main content

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

Why the Buildservice is currently not for endusers

Everytime, when I hear people rendering homage to the openSUSE Build Service as “nice tool for endusers to get packages”, I’m a bit confused. From my point of view, the Build Service in it’s current state is not really usable for endusers.

Here are some reasons why:

  1. No displayed License before adding the repository (have a look at the Non-OSS or Education Repositories to get an idea how this works) – this might be important if people crash their hardware after adding a repository with special kernel modules without being informed about possible problems…
  2. No package groups called “patterns” – so people can’t get an easy overview about the various software areas a project provides (using YaST -> Software -> RPM Groups is not usable for me since someone decided to show just a plain structure there).
  3. No package translations (sometimes I like to see the Summary and Description of a package translated in my own language to understand the real area of application for this package).
  4. As the Repositories change over and over again (sometimes just because a dependend package in another project has changed), you need to download at least the metadata of a project again and again. For the Education repository in the Build Service this means: transfering 4MB of data each time you call “zypper”. Not really nice for people with a low bandwith.
  5. Endusers will “upgrade” their installed packages again and again – without knowing the real reason for this upgrade until they can have a look at the package changelog (hoping the developer has added some informations there). Not even the Factory distribution has this problem with automatic rebuilds (resulting just in increased release numbers) and no information for endusers why they had to download tons of MB each week…
  6. Real Packagers use their Build Service repositories for development and testing – so some packages will likely be broken during this phase – and just the packager knows when it will be really “stable”. (I’m talking about “real packagers” as I often see people using their home projects in the Build Service just to create an own repository containing packages they use – just by linking packages from other projects without any changes. But this is another topic…)

Projects like KDE or GNOME try to balance some of this problems by using the “publish disabled” option until they want to release a new version of their project. But this makes testing for developers and testers harder: with publish disabled, developers and testers can’t easily download and test new packages via the synced, public repositories – they have to download their packages via the API of the Build Service one by one.

With the upcomming releases of the Build Service, this will hopefully change. Up with 1.5 project admins can create a “full featured YaST Repository” for their projects covering the points 1, 2 and perhaps 3. But I think we also need more or less “frozen” repositories beside the current project repositories to cover 4, 5 and 6.

These “frozen” repositories should IMO be placed in separate directories (like the official openSUSE distribution directories) to make it clear to everyone that these repositories have an “enduser focus” and not a “developer focus”. This way, a project like KDE or GNOME could:

  • use the current repositories below download.opensuse.org/repositories as their “bleeding edge”  development repos for packagers and testers.
  • have a separate enduser repository with additional features like patterns and translations using the “ftp tree generation” feature.

…and thats the reason why the summary of this blog contains the word “currently” – I think the Build Service is on a good way to be a really good solution for developers and endusers. But we should find a final solution for the open issues mentioned above before we point endusers to this tool.

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

How developers see openSUSE

You probably know that a lot of openSUSE developers are sitting in the SUSE office in Prague, Czech Republic. They are also openSUSE users.

The whole story started by a flame on a mailing list why some of us are not happy with the current state of openSUSE. It turned out there is a lot of different issues. So, we’ve met on a raining winter Friday 3 weeks ago to collect those issues as well as things that people consider to be good about openSUSE.

The result of the hours-long discussion is a list of positive and negative things about openSUSE, very subjective view of the group of developers in Prague. Go, look at the list. There is a lot of problems that I personally see lurking in our community, spelled out loud. The range is wide, from basic community issues to very technical problems that are basically missing features in the distribution.

So, we have collected the feedback. But the question is, what to do with it?

Firstly, I believe the lists are great food for thought. You might not agree with everything, but still, there is some truth in it. At least, those are problems that people consider important enough to try to solve them – encouraging.

Secondly, consider this blog as call for contribution. If you believe some of the areas are really worth improving, get in touch with people listed on the wiki, improve the description  in the wiki, propose solutions. One restriction though – please, do not add additional items to the page. We want to keep the ideas where they belong – features eventually to end up in openFate, project-related problems on the mailing lists, …Also, this is not a general list of issues the openSUSE project needs to address. As I’ve written above – the page is a subjective view of a group of people. If you think we need a more general approach, please, bring the idea on openSUSE mailing lists.

Looking forward to your feedback!

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

Overloading library function

Sometimes during testing (especially while testing maintenance update), I come to a problem how to test the reaction of the program to an unusual function return value (e.g. special error), data, etc. The problem is, that I need to test the unmodified program binary and that it is almost impossible to set up a situation when the error "naturally" occurs.

If the function is in a shared library, there is a simple way to force the program to use another function instead of the one from the library. The program will call the new function, which will return the specific value (unusual error I need to test).

The magic "tool" is LD_PRELOAD variable. When the program is loaded to memory, libraries specified in LD_PRELOAD are loaded before libraries needed by the program. If I have function strdup() in my custom library (loaded by LD_PRELOAD), it will be used instead of strdup() from standard C library.

So for (very simplified) example, let's say I need to test program prog correctly checks whether strdup() returns NULL (I assume that prog segfaults on NULL access): I'll write simple library libexploit which will only contains my new strdup().

exploit.c:

char *strdup(const char *s)
{
      return NULL;
}

Makefile:

all: libexploit.so.1.0

clean:
      rm -f libexploit.so.1.0 *.o

libexploit.so.1.0: exploit.o
      gcc -shared -Wl,-soname,libexploit.so.1 -o libexploit.so.1.0 exploit.o

exploit.o: exploit.c
      gcc -Wall -fPIC -c exploit.c

Now when I make the simple library, I'll get result libexploit.so.1.0 which I'll preload to the program:

LD_PRELOAD="`pwd`/libexploit.so.1.0" prog

And it is all - the program got NULL from all calls to strdup().

Simple, right? There is one catch, however. Or two.

First problem is that the original function is replaced by the new one, so you cannot call the original one (not even from your "new" function).

Second problem is that even the original library will start using your function. So if the library is using the overloaded function, it uses the new one. This may result in unexpected library behavior.

Both these problems are not (AFAIK) solvable in a easy way. The only way I've found out so far is the re-factoring of the original library in following steps:

  1. Rename the original function - e.g. from strdup() to __strdup().
  2. Replace all calls of function strdup() with calls of function __strdup() in the library source - this will ensure that the library code will always call the correct function.
  3. Create new function strdup() which will contain the testing code (and can also call the original __strdup() function).
  4. Compile the library and load it with LD_PRELOAD as described above.

Now, that's finally all.

(This text has also been published on openSUSE wiki)

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

MonoDevelop 2.0 beta 1

Yet another step towards 2.0 release. We released Beta 1 last week with many fixes and some new interesting features (here are the release notes).

The one I like more is the support for per-project policies. This feature has been planned for long time but other work has been delaying it. Me and Michael Hutchinson had a chance to talk quite a lot about it while I was at Boston a couple of months ago. The policies model allows setting properties at global, solution, folder and project levels. Settings such as tab width can be defined in any of those levels and will cascade down to the lower levels (where it can be overriden if required). Many settings are already available in this way, and many more will be in future releases.



Another new feature, or rather improvement, is the support for multiple frameworks. MD already had support for targeting the 1.1/2.0 CLR for quite a long time, but did not have the concept of 'target framework', which is more generic. For example, .NET 3.0 is based on the 2.0 CLR and it just includes some additional assemblies. What complicates things a bit is that Mono does not follow the .NET releases, so for example Mono 2.0 includes bits from all .NET versions. To simplify all this and to be compatible with MSBuild, it is now possible to select the target .NET framework, which includes 1.1, 2.0, 2.1 (Silverlight), 3.0 and 3.5. The project system is fully aware of the chosen target framework, so for example it won't let you reference a 3.5 project from a 3.0 project.

The source editor keeps improving in many ways. Mike Krueger has spent quite a lot of time fixing issues in code completion, which now works in many more contexts. My contribution on code completion (besides stabilization work in the parser database) is support for completion of generic types with constraints. For example, in the following class code completion is showing the Dispose method because there is a constraint forcing the generic argument to implement it:



There are other improvements, such as the new Go to File dialog I blogged about some time ago, better support for completion in ASP.NET projects, and fixes in the GTK# designer. There is still a lot of work to do, but we are getting close to 2.0.
a silhouette of a person's head and shoulders, used as a default avatar

Object Oriented UI for YaST

Hello!

After my last blog I worked on YaST (what a surprise) and didn't have any time to post anything until now.
Meanwhile I read some chapters from the "Thinking in Java" book. There are some chapters about OOP in general and it brings me to idea, how it would be great in YaST. As a side effect it also means get away from ycp ;-). Thanks to UI independence I can use Python with the YaST UI.

Here's some code example:

widget_library.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import yui

class MainDialog:
def __init__(self):
self.factory = yui.YUI.widgetFactory()
self.dialog = self.factory.createMainDialog()
def __del__(self):
self.dialog.destroy()

class Popup:
def __init__(self):
self.factory = yui.YUI.widgetFactory()
self.dialog = self.factory.createPopupDialog()
def __del__(self):
self.dialog.destroy()


class TableDialog:
def __init__(self, d):
self.f = d.factory
vbox1 =self.f.createVBox( d.dialog )
self.f.createVStretch(vbox1)
hbox1 =self.f.createHBox( vbox1 )
self.f.createHStretch(hbox1)
self.f.createHSpacing(hbox1,1)
vbox2 =self.f.createVBox( hbox1 )

self.Table( vbox2 )

vspace =self.f.createVSpacing(vbox1,2)
self.f.createHSpacing(hbox1,1)
self.f.createHStretch(hbox1)
self.f.createVStretch(vbox1)

etype=-1
while etype!=5:
event = d.dialog.waitForEvent()
etype = event.eventType()
self.HandleEvent( event )
print etype

def Table(self,parent):
vbox3 =self.f.createVBox( parent )
self.customWidget(vbox3)
theader = yui.YTableHeader()
theader.addColumn("Targets")
self.table =self.f.createTable( vbox3, theader )
hbox2 =self.f.createHBox( vbox3 )
self.pbAdd =self.f.createPushButton( hbox2, "&Add" )
self.pbEdit =self.f.createPushButton( hbox2, "&Edit" )
self.pbDel =self.f.createPushButton( hbox2, "&Delete")
self.enableDisableButtons()

def customWidget(self,parent):
pass

def HandleEvent(self,event):
if (event.widget()==self.pbAdd):
self.handleAdd(event)
elif (event.widget()==self.pbEdit):
self.handleEdit(event)
elif (event.widget()==self.pbDel):
self.handleDel(event)
self.enableDisableButtons()

def enableDisableButtons(self):
self.pbEdit.setEnabled(self.table.itemsCount()>0)
self.pbDel.setEnabled(self.table.itemsCount()>0)


main.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import yui
from widget_library import *

class TargetDialog(TableDialog):
def __init__(self,d):
TableDialog.__init__(self,d)

def customWidget(self,parent):
hbox =self.f.createHBox( parent )
self.f.createInputField(hbox, "Target")
self.f.createInputField(hbox, "Identifier")

def handleAdd(self, event):
print "add target item"
def handleEdit(self,event):
print "edit target item ..."
def handleDel(self,event):
print "delete target item ..."

class MyTable(TableDialog):
def __init__(self,d):
TableDialog.__init__(self,d)

def handleAdd(self,event):
print "adding ..."
TargetDialog(Popup())

def handleEdit(self,event):
print "edit item ..."
def handleDel(self,event):
print "delete item ..."

if __name__== "__main__":
td = TargetDialog(MainDialog())



I know that code is not nice and not very useful, but here's some nice OOP examples:
inheritance, composition, etc ...

Easily put into constructor, what kind of dialog I want:
TableDialog(MainDialog()) or TargetDialog(Popup())

Inherit some class and override methods you want (see MyTable.handle*())
This is much better than generate file from template (as we do now).

I like this way and I'll keep working on it during my ITO.

Bye,
Michal
a silhouette of a person's head and shoulders, used as a default avatar
the avatar of Sandy Armstrong

Tomboy 0.13.5 Brings a Better Windows Installation Experience

Today I released Tomboy 0.13.5. It has a bunch of nice fixes, including updates to Benjamin Podszun's Gtk.Print rewrite of Tomboy's printing add-in (making printing available on all platforms). For Windows users, this is the first time that you should be able to easily install gtk-sharp and Tomboy without having to muck around with your system. But we wouldn't want it to be too easy, so there are some caveats.

From http://live.gnome.org/Tomboy/Installing/Windows :

Instructions for installing a Tomboy Windows release

Upgrading from Tomboy 0.13.4 or earlier
  1. Uninstall Tomboy.
  2. Uninstall any existing versions of gtk-sharp you may have installed.
  3. Continue with Installation instructions.
Installation
  1. Install Novell's gtk-sharp 2.12.8 or newer.
  2. Restart.
  3. Run Tomboy installer 0.13.5 or newer.
  4. Enjoy!
Importing notes from Linux (optional)
  1. On your Linux box, copy all of the *.note files out of ~/.tomboy .
  2. On your Windows box, quit Tomboy.
  3. On your Windows box, copy all the *.note files from Linux into %APPDATA%\tomboy .
Please please please don't hesitate to file bugs for any problems you experience.

Thanks so much to Mike Kestner for working his ass off (on his own time) updating the gtk-sharp installers, making them easier to develop and build, and fixing the issues reported by Tomboy users. Apps like Tomboy, Banshee, and GNOME Do would simply not exist without all of his hard work.

the avatar of Matthias Hopf

More r6xx mysteries

I have used up half of my weekend to understand an issue with r6xx chips - when sending two draw commands on my laptop, I got system freezes, DRM oopses, and kernel panics - though the code was actually pretty simple.

It really took a long night (and approx. a hundred reboots) to find this:


When you want to
  • change VGT_INDX_OFFSET / VGT_MIN_VTX_INDX / VGT_MAX_VTX_INDX or
  • switch to a different shader
you have to re-set the Render target (CB_COLORx_BASE / CB_COLORx_SIZE / CB_COLORx_VIEW / CB_COLORx_INFO / CB_COLORx_TILE / CB_COLORx_FRAG / CB_COLORx_MASK, to be verified which actually influence anything), either before or after setting the registers for VGT or shaders.


Today in the office I found out that this is only necessary on my laptop's M72, on RV610, on RV630, and on RV635 - but not on RV670 or RV770. So this is chipset specific, but not VC releated...

What - as I assume - happens is that only a write to the render target registers stalls writing to the VGT and shader registers, so this seems to be some kind of flaw in the pipelining logic on some of the chips. As setting the render target again doesn't have a too big performance impact, I assume it's best to do it regardless of the chipset.
a silhouette of a person's head and shoulders, used as a default avatar

Latest and greatest(untested)?!

Linus released
  • 2.6.24 on January 24th 2008,
  • 2.6.26 on July 13th, 2008, and
  • 2.6.27 on October 9 2008

Here is when it reached the users
  • Gentoo 2008.0 released on July 6, 2008 has linux 2.6.24 which was ~5.5 months old.

Distros used by power-users seems to be always running slightly older version compared to the distros aimed at the layman! Yeah, but power users^Wdevelopers use the unstable/development/factory/head version of their favourite distro and not the released stable. But Ubuntu stable(!) is based on debian unstable! And debian stable is so outdated. opensuse seems to be quiet the latest but not straight from the unstable development snapshot.

p.s: I use only opensuse regularly among these distros. So any mis-information and bias is likely. ;)

the avatar of Katarina Machalkova

Install more packages? ["Yes"]["No"]

When it comes to software, its users are usually very picky creatures :-) Put feature X in and hear them complaining how bad and user-unfriendly you actually made it. If they complain long/loudly enough, finally decide to remove it and be sure that so-far silent majority starts to complain even more.

It was the same with YaST package manager and pop-up question from the title of this post. I'm sure we all remember that one:



It was introduced in openSUSE 10.1 (aka BrokenSwManagement edition) in order to alleviate suffering of the poor users forced to use our package management (powered by zmd and baby-libzypp) with ultra-slow start-up. libzypp grew faster and faster over the time, but the pop-up question remained and (quite reasonably) it started to annoy users. "Why do I have to click to have this crappy pop-up disappear?" they asked. "I've made my choice, installed all packages I wanted, so I want to answer no further questions."

After many heated discussions, we finally made the pop-up go away in openSUSE 11.1 After clicking on 'Accept' and installing all packages, package manager simply ended. That, of course, made the other half of the users speak up: "Why YaST does not ask anymore whether I want to install more packages? I don't want to start package manager anew each time. I simply want to have an option to install something more I forgot about in the first round."

In openSUSE 11.2, my colleague lslezak (now the link to his blog should be here, but he is too shy to have one :)) used really ingenious way of cutting the Gordian knot - he made the behaviour on exit from package manager configurable. And not only that - besides an option to close package manager (for those who want to be done with it) and option to restart it (for those who may want to come back and select something more), he added a third one. When the package installation is over, you can choose to display a neat summary of what has been installed/deleted, how long did it take and view some detailed logs. Then, you can either finish, or go back to install more packages:


Now all you have to do is to open /etc/sysconfig/yast2 file in your favourite editor and set PKGMGR_ACTION_AT_EXIT variable to some reasonable value. Please find more detailed information here.

"But I don't want to edit some cryptic file manually," you might think. "Isn't there any other way?" Well, of course there is. YaST ncurses package manager has a brand new menu that allows you to pick the exit action of your choice in a few key presses:


There are some minor things left to polish, but it basically works by now. Better don't ask me how the sysconfig variable is actually written :-) It took me by surprise to realize that libzypp's interface to sysconfig is read-only, so I'm impatienly waiting for Augeas ;-)