Archive for April, 2009
Ruby has a nice, but very dangerous feature called open classes. That means you can extend any class definition if you want it.
This example shows it
#!/usr/bin/ruby class Foo def do_foo return "foo" end end aFoo = Foo.new() puts aFoo.do_foo() class Foo def do_bar return "bar" end end puts aFoo.do_bar()
That means you dynamically extend the definition of Foo class, so the last line prints “bar”.
Python behavior is different, because it does not allows this extending. Python just redefines a class Foo, so new instance of Foo will have a do_bar method only. But this not affected an existing ones, like Ruby does.
class Foo: def do_foo(self): return "foo" aFoo1 = Foo() class Bar(Foo): def do_nothing(self): pass print issubclass(Bar, Foo) print isinstance(aFoo1, Foo) class Foo: def do_bar(self): return "bar" aFoo2 = Foo() aBar = Bar() print issubclass(Bar, Foo) print isinstance(aFoo1, Foo) print isinstance(aFoo2, Foo) print dir(aFoo1) print dir(aFoo2) print dir(aBar)
But what about method injection? My solution is based on ideas of Recipe 81732: Dynamically added methods to a class.
import types def funcToMethod(func, instance, method_name=None): cls = instance.__class__ if type(instance) != types.TypeType else instance setattr(cls, \ method_name or func.__name__, \ types.MethodType(func, instance, cls))
And that’s all. The funcToMethod bounds func to instances’s class and allows under method_name (default name is a same as a function one). So lets do some testing.
class Foo(object): def list(self): return [meth for meth in dir(self) if meth[:3] == 'do_' and type(getattr(self, meth)) == types.MethodType] def do_bar(self): return "bar" def do_foo(inst): return "foo" class Bar(Foo): def do_nothing(self): pass aBar = Bar() aFoo1 = Foo() print aFoo1.list() # calling it with class instead of instance is also possible and is equivalent #funcToMethod(do_foo, Foo, "do_foo") funcToMethod(do_foo, aFoo1, "do_foo") aFoo2 = Foo() print aFoo1.list() print aFoo2.list() print aFoo1.do_foo() print aFoo2.do_foo() print aBar.list() print aBar.do_foo()
When you run the code, you will see that funcToMethod adds a new method to Foo class and this changes both existing and new instances as Ruby does too. And subclassing is not a problem, they are be affected too.
Urgh, the OpenOffice_org 3.1 beta6 packages are currently available only for 5 localizations: English(American), German, Japanese, Czech, Hungarian. I forgot to enable all localizations in the final build (bnc#498906). I have just triggered the full rebuild but it will take one or two days until the packages are available.
I am really sorry for the inconvenience.
I’m happy to announce that OpenOffice.org 3.1 beta6 packages are available in the Build Service OpenOffice:org:UNSTABLE project. They include many upstream and Go-oo fixes. Please, look for more details about the openSUSE OOo build on the wiki page.
The packages are beta versions and might include even serious bugs. Therefore they are not intended for data-critical usage. A good practice is to archive any important data before an use, …
We kindly ask any interested beta testers to try the package and report bugs.
This build includes an alpha version of OpenXML export filters (DOCX, XLSX, PPTX). We also added many fixes to the OpenXML import filters. They should be able to import and export simple documents now. These changes affected also the import and export filters of the old binary file formats (DOC, XLS, PPT). So we kindly ask anyone to try this functionality and report bugs especially in the import and export of the old binary file formats.
Other information and plans:
I would like to provide beta7 or rc1 build the following week. The openSUSE final release might be delayed one or two weeks after the upstream because of the extra changes. The current upstream release date is May 7, 2009.
There are various ways to build a live cd and since 11.2 Milestone 1 there is a new one: clicfs. I’ll try to explain:
The challenge with a live cd is the size of the CD and what you put on it, 700MB is not enough for a typical desktop experience. So most (if not all) distributions use compression to squeeze about 2GB on a CD. There are various compression file systems, most famous is squashfs – which is since 4.0 even in the kernel mainline (>= 2.6.29) and uses gzip compression, even though there exist patches to make it use lzma. These lzma patches are not very often refreshed and not officially supported by the squashfs authors. This might actually change soon as kernel 2.6.30 has lzma decompression built in – but it’s not there yet.. There is also cloop, which I think is exclusive to Knoppix. It’s also gzip compressed and has a different semantic than squashfs. More to that later.
But however you compress, it comes with a catch: your compression will create a read only file system. But you need to write to it, not to all places, but in various (/var/run, /var/tmp, /tmp/, often in /etc, surely in /home). For a long time, the live cds existent created one large tmpfs and symlinked all the places and files that needed writing. But this is pretty unflexible and also takes more memory than really necessary. The new solution was first unionfs, which has a long history with many ups and downs and then later aufs. Aufs is Another unionfs and is the reason for one of the downs of unionfs. With a union you can generate a file system that is actually a map of two: the read only part and a read write part. But neither of them has good short term prospect of getting in the kernel mainline (aufs is trying hard at the moment, but still my personal guess is: 11.2 will pass without it being in mainline).
Some distributions have no problem with using large kernel patches, but for openSUSE it became more and more of a problem. Every kernel update broke it and the way aufs works is not easy to adopt to kernel changes – which is the reason the aufs author is pushing into mainline. Let’s wish him luck.
So I looked around and tried unionfs-fuse and deltafs. Both are fuse file systems avoiding the need of large kernel patches to create a compressed read write file system. Both had their issues, deltafs is just a prototype at the moment and unionfs-fuse is still pretty young too (unionfs-fuse fixed most of my issues meanwhile, so possibly it will come back to me 🙂
Then I looked closer at what Fedora(10) does: they do it completely different than most distributions I checked so far. They use a huge ext3 file system with their read only content, compress it in squashfs and then use a device-mapper snapshot on top of it to make it read write into a device-mapper copy-on-write file. Very interesting, in theory very slow – not slower than 11.1 in practise. So kiwi supports that mode since v3.29 (called “dmsquash”). But as the 11.2 kernel OOPSed with such loopback mounted file systems (fixed meanwhile) I kept on looking for alternatives. And as unionfs-fuse was so close and has also support for cow, I thought if I can’t do my own fuse filesystem that combines the best of all. Actually I thought out loud while eating doener with Michael and Jan and so I hacked doenerfs as prototype in just an afternoon.
The idea is very simple: Instead of using device-mapper with squashfs snapshot and copy-on-write file I put the ext3 file system in another file system just made to compress it: doenerfs. That filesystem uses xz libraries. So you can mount the compressed image and then mount the ext3 file system loop and get a read write file system. Of course it comes with a catch: the writes don’t go anywhere but in the memory of the fuse driver. The more you write, the bigger the process gets. But in the end it doesn’t matter what uses your RAM, tmpfs or fuse mounts.
Meanwhile I extended the code quite a bit in adding some possibly unique features and renamed it to clicfs: Compressed Loop Image Container. The 11.2 Milestone 1’s Live CDs use it’s first version.
As the file system is explicitly made to compress another file system, I only need to support one file with a fixed name and with a known size and all that – a lot of complexity of other file systems is gone. So I could spend most time developing the interesting parts 😉
The fuse driver has only 3 options and each of them marks a feature:
- -m adds sparse blocks at the end of file. The actual ext3 file system has 0 blocks free, the sparse blocks are appended during boot of the livecd. After that the live cd will resize the file system to match the gained room. And only blocks actually written to will end up in memory. Sparse blocks are only marked as not yet existent. Current live cds hard code 470MB, but it’s just some /proc/meminfo left to do and then it will have free space depending on RAM amount. So far the free space was limited by either what the ext3 image left free (fedora) or how much is in the tmpfs (aufs solution)
- -l logfile will create a log file with the access pattern. You can pass this log to mkclicfs to group the ext3 blocks in order in the compressed image. I use this while building the livecds to avoid seeks on the CD.
- -c cowfile puts the blocks that are written to in an extra file instead of RAM. This makes it possible to store them on an usb stick and load them at later boots. This is the newest and least tested feature.
The sources are at git.opensuse.org.
now out: kde4-skrooge 0.2.7. Published in openSUSE:Factory:Contrib and KDE:KDE4:Community.
On Saturday April 25th, the Nicaraguan OpenSUSE Community joined forces with the Free Software Community (GUL-Nic) to celebrate the Latin American Free Software Installation Festival, (FLISOL in Spanish).
The Festival took place at the Universidad Nacional de Ingenieria Campus (UNI-IES), reaching more than 300 visitors.
With the help of a unique identifier that is stored in every binary executable matching the executable, a coredump and the corresponding debuginfo together becomes really easy. You don’t need to know the package name and the version-release string to download and install the correct debuginfo package. This is achieved by extending the linker, some additional tools and the package management itself.
The issue caused by the OBS worker update on arm builds is fixed by a new qemu.
This new qemu version also has fixed the Fedora 10 @ ARM build problem.
So we have the following working ARM target distros available for ARM: Fedora 10, Debian 5.0 and Ubuntu 9.04.
Its a while since I posted the status about the ongoing work for ARM support in the OBS and for an openSUSE port. It all started with my participation in the OBS development as an external contributor. Then, on Hackweek 2008, we had the idea to enforce a new solution other than the traditional methods of compiling code either natively or via a cross compiler on a host system. The idea was to give build scripts as much of the target enviroment as they need to just work without changes in the packaging definition – in order not to change thousands of package descriptions which define a linux distribution.
A lot happened in the meantime. And I can now report some significant progess in bringing the joys of OBS and openSUSE also to all the ARM users:
To accelerate the openSUSE @ ARM development itself, we want to involve more people of the community. We have an IRC Channel #opensuse-arm for OBS and openSUSE @ ARM – i invite you to visit us there. We will also find a solution to bring the needed changes into the openSUSE Factory codebase so regular build for openSUSE can take place once the base system is working. I will inform you once we have a working base system that can be used to port many other packages. The soon starting Summer of Code Project “Porting openSUSE to ARM platform” is intended as the starting point here.
The next steps are to bring in all the useful applications into OBS, so you have the wide range of applications that is already available for x86 or powerpc then also on ARM. You will see interesting things happening during the next time here. To support this, more and more of the tested ARM targets will be made available also on the public OBS. I will follow up with status updates.