Tuesday, February 8, 2011

package testing made easy by conary rollback

Some time ago I came into a bug of foresight, FL-2639 - fails to boot due to libata-migrate. Then our lead developer António committed an updated recipe. But before new packages are made, I was asked to build the recipe and test it locally.

So I checked out the recipe, and 'cooked' it on my system.

cvc cook mkinitrd.recipe

The package was built and I installed it.

sudo conary update mkinitrd-6.0.93.ccs

But something seemed wrong, as you might guess from the libata-migrate warnings in the above screenshot.

So I asked António and confirmed the problem.


I didn't panic. As António said, I ran a single command and brought my system back to safety :)

sudo conary rollback 1

That's a typical scenario during foresight development, and part of what makes it a fun to work with conary.

Wednesday, February 2, 2011

foresight 2.5.0 ALPHA 2 released

Og Maciel 刚刚发布了 Foresight Linux 2.5.0 ALPHA 2.

Foresight 经过了一段很艰难的岁月,但是我们撑过来了 :) ALPHA1 发布之后,还是吸引了相当多的关注。根据 DistroWatch, Foresight 的关注度从 185 位, 升到 147, 又升到 115, 然后又升到了 47。

ALPHA2 下载链接,
* Foresight Linux GNOME Edition 2.5.0 x86:
    URL: https://www.rpath.org/images/foresight/27224/foresight-2.4.99+alpha2+2011.01.31-x86-dvd1.iso
    Size: 1.60 GB
    SHA1: 9068e94a0c6552409ae46893e2d32bbfedc0b442

* Foresight Linux GNOME Edition 2.5.0 x86_64:

    URL: https://www.rpath.org/images/foresight/27223/foresight-2.4.99+alpha2+2011.01.31-x86_64-dvd1.iso
    Size: 1.78 GB
    SHA1: f8fe9c020f97b114d9f543f427caa498c0f407ac

using conary api

Conary has a public API, through which you can have access to the packages on your system. Here is some quick examples.

1. Query packages installed locally, (equivalent of 'conary query')

1 # test1.py
2 import pprint
3 
4 from conary.conaryclient import ConaryClient
5 from conary.conarycfg import ConaryConfiguration
6 
7 c = ConaryClient(ConaryConfiguration())
8 troves = c.db.findTroves(None, [('dbus', None, None)])
9 pprint.pprint(troves)

$ python test1.py 
{('dbus', None, None): [('dbus',
                         VFS('/foresight.rpath.org@fl:devel//2-qa/1.4.0-0.3-1'),
                         Flavor('is: x86')),
                        ('dbus',
                         VFS('/foresight.rpath.org@fl:devel//2-qa/1.4.0-0.3-1'),
                         Flavor('is: x86_64'))]}
$ conary q dbus
dbus=foresight.rpath.org@fl:2-qa/1.4.0-0.3-1[is: x86]
dbus=foresight.rpath.org@fl:2-qa/1.4.0-0.3-1[is: x86_64]

2. Query packages in the repository, (equivalent of 'conary repoquery')

 1 # test2.py
 2 import pprint
 3 
 4 from conary.conaryclient import ConaryClient
 5 from conary.conarycfg import ConaryConfiguration
 6 
 7 cfg = ConaryConfiguration(readConfigFiles=True)
 8 c = ConaryClient(cfg)
 9 troves = c.repos.findTroves(cfg.installLabelPath, [('dbus', None, None)])
10 pprint.pprint(troves)

$ python test2.py
{('dbus', None, None): [('dbus',
                         VFS('/foresight.rpath.org@fl:devel//2-qa/1.4.0-0.3-1'),
                         Flavor('is: x86')),
                        ('dbus',
                         VFS('/foresight.rpath.org@fl:devel//2-qa/1.4.0-0.3-1'),
                         Flavor('is: x86_64'))]}

3. List files of a package, (equivalent of 'conary q --ls')

 1 # test3.py
 2 
 3 from conary.conaryclient import ConaryClient
 4 from conary.conarycfg import ConaryConfiguration
 5 
 6 c = ConaryClient(ConaryConfiguration())
 7 n, v, f = c.db.findTrove(None, ('m4:doc', None, None))[0]
 8 trove = c.db.getTrove(n, v, f, withFiles=True)
 9 for (pathId, path, fileId, version) in trove.iterFileList():
10     print path

$ python test3.py 
/usr/share/info/m4.info.gz
/usr/share/man/man1/m4.1.gz

Note that the trove you use for iterFileList() "will have to be a trove that has files -- a component or fileset, but not a package or a group". ('Trove' is a general name for package/component/group).

And there is also a second approach,

1 from conary.conaryclient import ConaryClient
2 from conary.conarycfg import ConaryConfiguration
3 
4 c = ConaryClient(ConaryConfiguration())
5 n, v, f = c.db.findTrove(None, ('m4:doc', None, None))[0]
6 iter = c.db.iterFilesInTrove(n, v, f, withFiles=True, capsules=False)
7 for (pathId, path, fileId, version, filename) in iter:
8     print path

4. List components of a package, (equivalent of 'conary q --troves' or 'conary q --all-troves'):

 1 # test4.py
 2 
 3 from conary.conaryclient import ConaryClient
 4 from conary.conarycfg import ConaryConfiguration
 5 
 6 c = ConaryClient(ConaryConfiguration())
 7 n, v, f = c.db.findTrove(None, ('kernel', None, None))[0]
 8 trove = c.db.getTrove(n, v, f)
 9 components = trove.iterTroveList(strongRefs=True)
10 for (n, v, f) in components:
11     print "%s %s %s - %s" % (n, v, f,
12             "Installed" if c.db.hasTrove(n, v, f) else "Not Installed")

$ python test4.py 
kernel:runtime /foresight.rpath.org@fl:2-qa-kernel/2.6.35.10-5-1 ~kernel.debugdata,~!xen is: x86_64 - Installed
kernel:vmware /foresight.rpath.org@fl:2-qa-kernel/2.6.35.10-5-1 ~kernel.debugdata,~!xen is: x86_64 - Installed
kernel:debuginfo /foresight.rpath.org@fl:2-qa-kernel/2.6.35.10-5-1 ~kernel.debugdata,~!xen is: x86_64 - Not Installed
kernel:build-tree /foresight.rpath.org@fl:2-qa-kernel/2.6.35.10-5-1 ~kernel.debugdata,~!xen is: x86_64 - Not Installed
kernel:configs /foresight.rpath.org@fl:2-qa-kernel/2.6.35.10-5-1 ~kernel.debugdata,~!xen is: x86_64 - Installed

That's it, some dirty examples and I don't know if it's the recommended way of doing things. And not all functions used above are official public APIs (now I'm using conary-2.2.9 and python-2.6.6). So take care, and better to install pycscope and poke around the source code yourself:)