Archive for September, 2008
enhancerepo 0.3.1 cooking in build service: deltarpm support
A new version of enhancerepo (0.3.1) is cooking itself in the build service.
The new feature is deltarpm metadata generation support and also some kind of smart deltarpm generation.
This means, enhancerepo can look which package has several versions in the repository, and generate delta rpms for N steps to the older versions. The default is one step, that is, only a delta rpm to the newest to the previous one. And then it can generate the metadata for you too (and add it to the index and such).
Example run:
# enhancerepo --disk-usage --keywords --eulas --create-deltas 2 --deltas -- /space/repo/duncan2 Adding eula: /space/repo/duncan2/zapping-0.9.6-72.eula to zapping-0.9.6-72-i586 Adding eula: /space/repo/duncan2/zaptel.eula to zaptel-1.2.10-70-i586 Adding keyword: /space/repo/duncan2/zaptel-debuginfo.keywords to zaptel-debuginfo-1.2.10-70-i586 Preparing disk usage... Creating delta - amarok-1.4.10-3-i586 -> amarok-1.4.10-17-i586 (1/2) Creating delta - amarok-1.4.9.1-53-i586 -> amarok-1.4.10-17-i586 (2/2) Saving /space/repo/duncan2/repodata/susedata.xml.gz .. Adding /space/repo/duncan2/repodata/susedata.xml.gz to /space/repo/duncan2/repodata/repomd.xml index repodata/susedata.xml.gz already exists. Replacing. Saving /space/repo/duncan2/repodata/deltainfo.xml.gz .. Adding /space/repo/duncan2/repodata/deltainfo.xml.gz to /space/repo/duncan2/repodata/repomd.xml index repodata/deltainfo.xml.gz already exists. Replacing. Saving /space/repo/duncan2/repodata/repomd.xml ..
Some important notes:
- It now requires ruby-rpm, which is available on the devel:languages:ruby:extensions repository.
- Be careful with running createrepo on top of a directory with deltarpms. createrepo will index them incorrectly as packages (So clean deltarpms, run createrepo, and then generate deltas with enhancerepo on top).
- I did not test this release as much as the latest
libZYpp, torrents and metalinks
Using only http for transfering files will be a thing from the past very soon. We know all the problems distributing content to large audiences companies face, and Peter Poeml knows it very well too.
So Peter mentored Gerard Farràs during the last Summer of Code, and the result was a ZYpp media handler that uses aria2 to download files, instead of curl. (May be aria uses curl for http then, I have no idea
).
aria2 is a utility for downloading files. The supported protocols are HTTP(S), FTP, BitTorrent (DHT, PEX, MSE/PE), and Metalink. It can download a file from multiple sources/protocols and tries to utilize your maximum download bandwidth. It even supports downloading a file from HTTP(S)/FTP and BitTorrent at the same time, while the data downloaded from HTTP(S)/FTP is uploaded to the BitTorrent swarm. Using Metalink’s chunk checksums, aria2 automatically validates chunks of data while downloading a file like BitTorrent.
The benefits is that aria knows about bittorrent, metalinks, etc, so this open the door for much better download failover in the future.
As we are aready on beta phase and we can’t switch such an important component, I merged the code, but disabled. That means ZYpp still uses curl, unless you enable the environment variable ZYPP_ARIA=1. That way you can play with it while it matures for 11.2 or something. There should be lot of features missing in the aria2 handler, so please have that in mind.
Thanks to Peter and Gerard for the handler.
The natural order of things…
Polyglot programmers
In the book “The Productive Programmer”, written by Neal Ford, there is a nice chapter that talks about an old topic: languages, and defines Polyglot programming as the kind of tendency in the industry to manage the complexity of current applications.
It is tempting to think that one language keeps the complexity low, but that is exactly the reason why languages keep coming. They usually try to become general purpose languages and start to get bloated or inheriting nonsense stuff.
While thinking on this topic. I started to remember lot of episodes in my life as a software developer. Having learned lot of my base in the KDE community, I was quite natural to think in the way Neal explains. In KDE people write since the beginning of the platform a good bunch of the static user interface descriptions in domain specific languages, which are transformed to more general languages (C++) at compilation time.
The very basics of Qt is C++ plus a “platform” and some specific add ons (another domain specific language for component communication) which are compiled into support code at compilation time. Code generation using DSL’s goes beyond that: Configuration for applications can be specified in a simple XML schema for the configuration domain and most of the code is generated. Therefore consistent, robust and bug free. For a KDE guy, this sounds natural (however it could be extended much more), and all the platform is like the book “Ola’s Pyramid”, where the lower levels are done using general languages (like C) and upper layers are done using more domain specific languages. We miss the intermediate part of scripting languages, but I am sure Plasma will be the first component following that natural order of things.
At that time I was learning, and the KDE “way” became natural. At the same time, that was the time when I discarded the Gnome platform completely. Mostly because I heard lot of FUD against KDE decisions at that time, lot of attacks and ignores towards a more common world, and then the world kinda inverted itself and used to be criticized stuff like use of preprocessor to add features to the language (Qt’s moc) : Welcome Vala? or the ignored dcop bus : Enter dbus, Object orientation (try to enter GObject ugh)… are now part of the “natural order of things”. I was kind of confused ( famous hackers claiming they won’t program apps in C again, uh? ).
As a side note, some developers, like Cornelius Schumacher and André Duffeck played with this concept of generating code much further. Like mixing models and user interfaces.
polyglot YaST
As a YaST developer, I keep thinking in the current code base, the directions we are taking, etc. The development field is full of new silver bullets, languages and things that make hard to keep the big picture if you are following previously unknown fields.
Surprisingly YaST is a very good example in the whole model. We abstract the low level system with a C++ made platform, and run a domain specific language called YCP on top, and have another domain specific language to manage the system configuration. It is a very good example of a complex platform that manages complexity using different languages, and it is a very mature platform at the same time. Of course there are lot of things that can be improved:
No usage of convention over configuration: There is an abuse of “skeletons”, that is, generating trees and code, putting it into version control, instead of doing most things magically by convention. (Very similar to the difference of rails to Java use of XML).
Defining user interfaces using code is ok as long as the code is not where it should not be. And the code base has this problem. Having an external DSL for this helps forcing you to separate things.
Hard to bind to the platform: Writing components is boring and over engineered. It works for complex cases (like defining your own type of component functions), but fails for the simple case. Try doing a ruby extension. It is easy. I think this is something we should improve. There are some basic support like adding some type information (using a DSL) on the headers and parsing that.
We should check and recheck that we are not repeating ourselves. Duplicated functionality, declarations and implementations.
Code generation for services
Now that we are walking towards the world of services, Web and such, it is time for new ideas. It is interesting to see big players trying to solve difficult problems, and coming up with natural solutions, like the case of Google with their protocol buffers, and Facebook with Thrift (paper).
Thrift is more interesting, as it comes from the situation of having to develop different services that need to communicate without needing to care much about what was used to build that component (SOA approach, which is not very different to what we are solving with dcop-ng (aka dbus) in the desktop scenario), but imagine dbus is your network, and thrift is the Qt dbus binding generator or dbusxml2something.
Thrift is a software framework for scalable cross-language services development. It combines a powerful software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, and Ruby. Thrift was developed at Facebook and released as open source.
Thrift allows you to define data types and service interfaces in a simple definition file. Taking that file as input, the compiler generates code to be used to easily build RPC clients and servers that communicate seamlessly across programming languages.
Now that schubi has been doing quite progress on exposing some YaST functionality via http (result of the last workshop), I am really curious if we can define our platform, and tackle some problems by defining very domain specific tools that can save us from repetition. Will see.
Introducing enhancerepo 0.3
Introduction
You may know that we are slowly heading to use the rpmmd format as the default one. We already do for the build service since the beginning, and the only remaining part is the media.
Therefore, we have been following an strategy of, at the same time, extending rpmmd with our own extensions, but at the same time, talk to the yum people in order to think in more long term about changes in the format.
Right now, in the openSUSE 11.1Beta code, you find the following extensions:
- updateinfo.xml (patches, same Format as Fedora)
- deltainfo.xml (delta-rpms, same format as yum-presto, different name)
- suseinfo.xml (repository extra data)
- susedata.xml (package extra data, like eulas and disk usage per mount point)
Apart of that, we sign our repositories.
Even for testing our own stuff, it became tedious to add extra metadata to repositories created with createrepo.
enhancerepo
Enhancerepo allows you to inject all the extra metadata to repositories in an easy way. It takes care of updating the index and compressing the files.
Features
- Sign repositories
- Generate eulas from text files with certain name conventions (package.eula)
- Generate keywords from text files with certain name conventions (package.eula)
- Add disk usage per mount point information
- Add repository expiration time (for outdated mirror autodetection)
- (expermental and incomplete) generation of updateinfo.xml
Usage
Usage ----- enhancerepo [OPTION] ... DIR -h, --help: show help --sign keyid Generates signature for the repository using key keyid --updates Add updates from *.updates files and generate updateinfo.xml SUSE specific repository data (suseinfo.xml): --expire time Set repository expiration hint (Can be used to detect dead mirrors) --repo-product prodname: Adds product compatibility information --repo-keyword keyword Tags repository with keyword SUSE specific package data (susedata.xml) --eulas Drop packagename.eula files and the attributes will be added to susedata.xml --keywords Drop packagename.keywords files and the attributes will be added to susedata.xml --disk-usage Add disk usage information the attributes will be added to susedata.xml Note: your .eula or .keywords file will be added to a package if it matches its name. If you want to add the attributes to a specific package, name the file name-version, name-version-release or name-version-release.arch DIR: The repo base directory ( where repodata/ directory is located )
Download
Packages available here.
git clone git://git.opensuse.org/projects/enhancerepo
Introducing ZYpp services
Credits
The following cool stuff would have not been possible without the hard work of Jan Kupec, Michael Andres and Michael Calmer, who implemented and tested this stuff. The original concept dates back from ZLM and the Novell Customer Center.
Usecase #1: The project with multiple repositories and layers
Imagine the following usecase (with this one I am using some real request from our KDE guys)
The build service provides a KDE4 repository. Which in turn requires the Qt4 repository, because is built on openSUSE 11.0 + the new Qt4 repo.
When looking at this problem, repository dependencies is what comes to head in the first place. But forget about them. If package dependencies are complicated right now, imagine adding a secondary (and duplicated) layer of information. Packages already know their dependencies.
Now imagine our KDE guys can provide an URL, which you add to zypper. And this url returns a dynamic list of repositories. And zypper adds and remove repositories based on the information returned by this url on every refresh.
Usecase #2: Update repositories based on the customer
This is actually where services where originated. Services were present in Novell ZenWorks. How it works?
The service url nu.novell.com is added to the system. But in this url also a customer id is present as a http username. When you registered, Novell knows the product this customer is linked to, and can return a dynamic list of update repositories based on the customer preferences, products and entitlements and the customer does not need to keep them in sync.
Now that we don’t have Zenworks in the base system, we still want this cool functionality for our customers.
Technically, this even allows us to offer hotfixes to L3 supported customers on the fly!
Usecase #3: Dynamic repository collections
You are a build service user, and you have an account, and of course you have a list of watched projects you are interested to. What if you could keep your system repositores in sync with your watched project list.
Or what if the build service could offer a service based on keywords or other data: like http://build.opensuse.org/services/mostpopular/repo/repoindex.xml would contain dynamically the 15 most popular repositories. You add that service, and then ZYpp does the work for you of adding new popular repositories, and remove the old ones.
Quick test
For a quick test, I needed a service provider, and I have none. I could have used our Subscription Management Tool, which can act as a local proxy replacement of a Novell Update service provider, but I decided to implement a quick and dirty service that could be used as an example for other people that have nice ideas for this stuff.
So I created a rails application, a very simple one, that returns a dynamic repository index by searching for the “emacs” keyword using the opensuse-community search API.
require 'open-uri'
require 'rexml/document'
require 'uri'
include REXML
class RepoController < ApplicationController
def index
# do a package search on a keyword
f = open('http://api.opensuse-community.org/searchservice/Search/Simple/openSUSE_110/emacs')
buffer = f.read
doc = Document.new(buffer)
repourls = Set.new
counter = 0
doc.elements.each('ns2:packages/package/repoURL') do | repourl |
# get all repourls
repourls.add repourl.text.to_s
end
# create the repoindex
outdoc = Document.new
root = Element.new('repoindex')
outdoc.add_element root
counter = 0
repourls.each do |repourl|
al = URI.parse(repourl).path.gsub(/\/repositories\//, '').gsub(/[\:]/, '').gsub(/\//, '_')
root.add_element 'repo' , { 'url' => repourl,
'alias' => al }
end
render
ml => outdoc.to_s
end
end
And I need also to configure a route, as the service is searched in the service url + “repo/repoindex.xml”.
map.connect ':controller/repoindex.xml', :action => 'index'
Requesting my new service http://localhost:3000/repo/repoindex.xml returns me the following.
<repoindex>
<repo url="http://download.opensuse.org/repositories/Education:/desktop/openSUSE_11.0" alias="Education_desktop_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/server:/mail/openSUSE_11.0" alias="server_mail_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/home:/tiwai/openSUSE_11.0" alias="home_tiwai_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/home:/sjcundy/openSUSE_11.0" alias="home_sjcundy_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/home:/hmacht/openSUSE_11.0" alias="home_hmacht_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/home:/marcinzalewski/openSUSE_11.0" alias="home_marcinzalewski_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/home:/beyerle/openSUSE_11.0" alias="home_beyerle_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/home:/dsteuer/openSUSE_11.0" alias="home_dsteuer_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/M17N/openSUSE_11.0" alias="M17N_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/repositories/home:/jefferyfernandez/openSUSE_11.0" alias="home_jefferyfernandez_openSUSE_11.0"/>
<repo url="http://download.opensuse.org/distribution/11.0/repo/oss/suse" alias="_distribution_11.0_repo_oss_suse"/>
<repo url="http://download.opensuse.org/repositories/home:/maw:/bzr/openSUSE_11.0" alias="home_maw_bzr_openSUSE_11.0"/>
</repoindex>
Adding your service can be done with zypper:
# zypper sa http://localhost:3000 myservice Service 'myservice' has been successfully added.
As you may note, services have their own commands. every repository not part of a service is also a service. So working with repositories at the service level basically groups all repositories that belong to the same service.
Now, when you refresh the service:
# zypper refs
Refreshing service 'myservice'.
Adding repository 'Education_desktop_openSUSE_11.0' [done]
Adding repository 'server_mail_openSUSE_11.0' [done]
Adding repository 'home_tiwai_openSUSE_11.0' [done]
Adding repository 'home_sjcundy_openSUSE_11.0' [done]
Adding repository 'home_hmacht_openSUSE_11.0' [done]
Adding repository 'home_marcinzalewski_openSUSE_11.0' [done]
Adding repository 'home_beyerle_openSUSE_11.0' [done]
Adding repository 'home_dsteuer_openSUSE_11.0' [done]
Adding repository 'M17N_openSUSE_11.0' [done]
Adding repository 'home_jefferyfernandez_openSUSE_11.0' [done]
Adding repository '_distribution_11.0_repo_oss_suse' [done]
Adding repository 'home_maw_bzr_openSUSE_11.0' [done]
Repository 'FATE' is up to date.
Repository 'KDE 4.1.x Packages (openSUSE_11.0)' is up to date.
Repository 'The (default) Factory KDE 4 desktop with extra apps (openSUSE_11.0)' is up to date.
Repository 'Current Qt 4.x packages (openSUSE_11.0)' is up to date.
Retrieving repository 'VirtualBox' metadata [done]
Building repository 'VirtualBox' cache [done]
Repository 'Latest YaST svn snapshots (openSUSE_11.0)' is up to date.
Repository 'Python and Python Modules (openSUSE_11.0)' is up to date.
Repository 'home:jnweiger' is up to date.
Repository 'PackageKit experiments (openSUSE_11.0)' is up to date.
Repository 'Network Utilities (openSUSE_11.0)' is up to date.
Repository 'openSUSE-11.0' is up to date.
Repository 'openSUSE-11.0-NONOSS' is up to date.
Repository 'openSUSE-11.0-Update' is up to date.
Repository 'openSUSE.org tools (openSUSE_11.0)' is up to date.
Repository 'outdated' is up to date.
Did you see how zypper automatically added the needed repositories? (it also would remove them if in the future the service does not list them).
Now, let list them:
Now if we list the services:
# zypper ls
# | Alias | Name | Enabled | Refresh | Type
---+-----------------------------+---------------------------------------------------------------------+---------+---------+-------
1 | myservice | myservice | Yes | No | ris
2 | FATE | FATE | Yes | Yes | rpm-md
3 | KDE_KDE4_Factory_Desktop | KDE 4.1.x Packages (openSUSE_11.0) | Yes | Yes | rpm-md
4 | KDE_KDE4_Factory_Extra-Apps | The (default) Factory KDE 4 desktop with extra apps (openSUSE_11.0) | Yes | Yes | rpm-md
5 | KDE_Qt | Current Qt 4.x packages (openSUSE_11.0) | Yes | No | rpm-md
6 | Virtualization:VirtualBox | VirtualBox | Yes | No | rpm-md
7 | YaST_SVN | Latest YaST svn snapshots (openSUSE_11.0) | Yes | Yes | rpm-md
8 | devel_languages_python | Python and Python Modules (openSUSE_11.0) | Yes | Yes | rpm-md
9 | home:jnweiger | home:jnweiger | Yes | Yes | rpm-md
10 | home_dmacvicar_packagekit | PackageKit experiments (openSUSE_11.0) | Yes | No | rpm-md
11 | network_utilities | Network Utilities (openSUSE_11.0) | Yes | Yes | rpm-md
12 | openSUSE-11.0 | openSUSE-11.0 | Yes | No | yast2
13 | openSUSE-11.0-NONOSS | openSUSE-11.0-NONOSS | Yes | No | yast2
14 | openSUSE-11.0-Update | openSUSE-11.0-Update | Yes | No | rpm-md
15 | openSUSE_Tools | openSUSE.org tools (openSUSE_11.0) | Yes | No | rpm-md
16 | outdated | outdated | Yes | No | rpm-md
17 | packman | packman | Yes | Yes | rpm-md
18 | rpms | rpms | Yes | No | rpm-md
19 | ruby | Ruby | No | No | rpm-md
20 | zypp_svn | ZYPP SVN Builds (openSUSE_11.0) | Yes | Yes | rpm-md
Do you see that all the added repositories are “hidden” behind the added service.
If you want to see them, then you need to list the repositories instead:
# zypper lr
# | Alias | Name | Enabled | Refresh
---+-------------------------------------+---------------------------------------------------------------------+---------+--------
1 | Education_desktop_openSUSE_11.0 | Education_desktop_openSUSE_11.0 | No | Yes
2 | FATE | FATE | Yes | Yes
3 | KDE_KDE4_Factory_Desktop | KDE 4.1.x Packages (openSUSE_11.0) | Yes | Yes
4 | KDE_KDE4_Factory_Extra-Apps | The (default) Factory KDE 4 desktop with extra apps (openSUSE_11.0) | Yes | Yes
5 | KDE_Qt | Current Qt 4.x packages (openSUSE_11.0) | Yes | No
6 | M17N_openSUSE_11.0 | M17N_openSUSE_11.0 | No | Yes
7 | Virtualization:VirtualBox | VirtualBox | Yes | No
8 | YaST_SVN | Latest YaST svn snapshots (openSUSE_11.0) | Yes | Yes
9 | _distribution_11.0_repo_oss_suse | _distribution_11.0_repo_oss_suse | No | Yes
10 | devel_languages_python | Python and Python Modules (openSUSE_11.0) | Yes | Yes
11 | home:jnweiger | home:jnweiger | Yes | Yes
12 | home_beyerle_openSUSE_11.0 | home_beyerle_openSUSE_11.0 | No | Yes
13 | home_dmacvicar_packagekit | PackageKit experiments (openSUSE_11.0) | Yes | No
14 | home_dsteuer_openSUSE_11.0 | home_dsteuer_openSUSE_11.0 | No | Yes
15 | home_hmacht_openSUSE_11.0 | home_hmacht_openSUSE_11.0 | No | Yes
16 | home_jefferyfernandez_openSUSE_11.0 | home_jefferyfernandez_openSUSE_11.0 | No | Yes
17 | home_marcinzalewski_openSUSE_11.0 | home_marcinzalewski_openSUSE_11.0 | No | Yes
18 | home_maw_bzr_openSUSE_11.0 | home_maw_bzr_openSUSE_11.0 | No | Yes
19 | home_sjcundy_openSUSE_11.0 | home_sjcundy_openSUSE_11.0 | No | Yes
20 | home_tiwai_openSUSE_11.0 | home_tiwai_openSUSE_11.0 | No | Yes
21 | network_utilities | Network Utilities (openSUSE_11.0) | Yes | Yes
22 | openSUSE-11.0 | openSUSE-11.0 | Yes | No
23 | openSUSE-11.0-NONOSS | openSUSE-11.0-NONOSS | Yes | No
24 | openSUSE-11.0-Update | openSUSE-11.0-Update | Yes | No
25 | openSUSE_Tools | openSUSE.org tools (openSUSE_11.0) | Yes | No
26 | outdated | outdated | Yes | No
27 | packman | packman | Yes | Yes
28 | rpms | rpms | Yes | No
29 | ruby | Ruby | No | No
30 | server_mail_openSUSE_11.0 | server_mail_openSUSE_11.0 | No | Yes
31 | zypp_svn | ZYPP SVN Builds (openSUSE_11.0) | Yes | Yes
There you have them all. You should also note that service configuration is very similar to repository configuration. Only services.d intead of repos.d.
Conclusion
As you can see, services implement a kind of “black box” repository, that allows subscription to dynamic repository sets. The concept is simple, optional (you can not use them at all), and the potential is very big, if people start to offer them.
Extremely easy driver installation
We have something really cool in.
How it works, usecase and experience.
The usecase. I have a webcam, but it does not work, because it requires the quickcam-kmp-default package. But I don’t know that.


You are in your desktop. You can see in the tray the applet telling you that there are security updates to install.
![]()
Now I connect the webcam to the computer:

Notice the tray icon. It went from “There are security updates available” to a “hardware” icon (we will add a more visible notification too).
![]()
Now you click on the icon and you see:

You click install, and after 10 seconds quickcam-kmp-default is installed.
See it live
Do you want to see it live?. I did a recording of the process as a flash movie.
Background
Since openSUSE 10.1, ZYpp has the ability to recommend packages based on drivers and other useful system information. Packages can supplement any namespace, which is in turn evaluated at solving time. This allows to automatic select drivers on installation, based on the machine hardware, for example.
You could also plug new hardware, and call
# zypper up
And that would recommend you to install the right drivers.
However this functionality was not used to its own potential. What we really wanted here was to recommend packages when hardware was plugged.
With PackageKit, filling that gap was possible, as we can easily talk to ZYpp from the desktop over dbus, using an abstracted interface.
So in the last weeks, Stefan Haas implemented support for this in our PackageKit ZYpp backend. Thomas Goettlicher added the needed glue in the kupdater applet. That is, listening to added devices events, and calling PackageKit to let ZYpp recommend new hardware.
Yesterday I sat to see it working. Some small one liners prevented it to work, but after some tweaking in the PackageKit backend, it worked really well. Thanks for everyone putting the pieces together.
Last week
After two weeks of relaxing vacation in the sunny Spain, I had a very busy week, with lot of internal milestones.
Cristian Rodriguez (judas_iscariote), our colleague working from Chile was here two weeks, but he was leaving on Tuesday, so Monday was the only day where both of us where in Nuernberg. Luckily, there was some time for chat and beer.
While you will see a constant flow of package check-ins containing lot of features. There are some other stuff worth to mention:
- YaST contains an interactive user interface debugger. (now with properties support too). (Stefan Hundhammer’s work)
- The distribution can be installed over serial line now (Steffen’s work).
Our trainee Alex has been blogging about the experience of learning YaST.
Oh, and I found the emacs extension I was looking for.
Critical thermal shutdown on Thinkpad x60
At the beginning it looked like some material for the Linuxhater blog
It happened a couple of times before, while working on my my X60 and suddenly the computer switched to shutdown mode and turned off. Uh? annoying!
Yesterday it happened again, and this time I was able to find the answer in the logs:
Sep 10 01:29:26 piscolita powersaved[2658]: WARNING (checkTemperatureStateChanges:217)
Temperature state changed to critical.
Sep 10 01:29:26 piscolita kernel: Critical temperature reached (128 C), shutting down.
Sep 10 01:29:26 piscolita shutdown[15371]: shutting down for system halt
Then googling I found out it is a bug in the kernel (google groups link, prettier), and it seems there is a patch for it. I think this is a good backport candidate for 11.0 updates.
update: tracking as bug #425077





Spam Poison