Friday, April 30, 2010

XBPS: version 0.5.0 released!

The XBPS 0.5.0 version has just been released. Release notes:

  • xbps-repo(8): fixed the 'search' target to also match patterns against its description, and not only from the package/version touple.
  • Cleaned up the code by using the LLVM's clang static analyzer, found two possible NULL pointer dereferences in error branches and dead code.
  • xbps-bin(8): added new flag '-p' for the 'remove' and 'autoremove'
    targets, to also purge the package(s) after successful removal.
  • xbps-repo(8): print a warning when registering a repository that has been already added previously.
  • Add proplib-0.4.1 source and use it in XBPS. This is to avoid
    an external dependency, so that we depend on the features of the
    internal library. This also means that proplib is not required anymore.
  • Added support to read/write gzip compressed plists by default, thanks to proplib-0.4 that gained new functionality.
You can see the detailed changelog and download the source tarball from:
https://launchpad.net/xbps/head/0.5.0

XBPS: LLVM/Clang, Apache packages

This is the list of recently added packages into the x86_64 official repository for XBPS:

  • llvm-2.7 (provides some subpkgs: clang, clang-devel, llvm-docs). The clang static analyzer helped me to found some warnings on XBPS and Portable Proplib.
  • apache-2.2.15 with the prefork MPM. A -devel subpkg to build modules is also provided.
  • apache-mpm-{worker,event}-2.2.15: Apache httpd binaries that provide different MPMs.
  • mod_fastcgi-2.4.6 - Apache 2.x module for the FastCGI protocol.

Along with some apache required dependencies (apr, apr-util), and some GNOME 2.30 updates, are
all related changes from this week in the xbps-src git repository.

I'm working in packaging MoinMoin with Apache/mod_fastcgi that I plan to use to document XBPS related stuff really soon.

Wednesday, April 28, 2010

XBPS: xbps-src gains new functionality

For the past days I've been working in bringing multiple improvements to the build system: xbps-src. It is a POSIX shell script with some more shell components that will fetch, check and compile source distribution files, to finally make XBPS binary packages.

Basically xbps-src works like the ports system on FreeBSD/OpenBSD or pkgsrc from NetBSD; but rather than running a make(1) command in a directory, you run the xbps-src command in a specific directory. The build template files, that specify how to fetch and build a binary package are shell scripts that understand a few variables (I shall document this in the future).

The structure to build packages is explained in the "building packages from source" document here:
http://xbps.nopcode.org/doc/building-from-source.html. Previously (before the last set of changes) there was a small shell script that required superuser permissions to bind mount /sys, /proc, /dev and the xbps-src main directory; that changed until the other day where I started using POSIX.1e capabilities support from the Linux kernel. They are explained in detail on its manpage capabilities(7).

I made three small C programs to bind mount and umount the required filesystems/mountpoints and another one to chroot into the master directory (the directory to chroot). The two mount programs use the CAP_SYS_ADMIN capability, and the last one uses the CAP_SYS_CHROOT. The programs need to have set those capabilities through the use of setcap(8). I added some security checks to the chroot code to make sure that you can't change root to / or to any other directory that the user doesn't own. With these changes in place you don't need to be the superuser anymore, the only problem is that you have to use a system that supports POSIX.1e capabilities and a filesystem with Extended Attributes... I'm sorry NetBSD you won't be able to use xbps-src.

The other set of changes implements a stow-alike approach while installing the packages in the masterdir (chroot directory), and all package files are now symlinked from its destination directory (if possible). That saves a lot of required space and helps to catch file conflicts and other problems. The master directory is where all packages are built, and stowned. The package is installed into its destination directory (/pkg-destdir) and stowned (symlinked) into the masterdir to be able to resolve dependencies.

[juan@nocturno ~]$ ls -l /storage/masterdir/
total 132
drwxr-xr-x 2 juan juan 4096 abr 28 01:29 bin
drwxr-xr-x 2 juan juan 4096 abr 26 21:52 boot
drwxr-xr-x 2 juan juan 4096 abr 26 05:29 dev
drwxr-xr-x 52 juan juan 4096 abr 28 00:45 etc
drwxr-xr-x 2 juan juan 4096 abr 21 15:26 home
drwxr-xr-x 11 juan juan 4096 abr 28 12:09 lib
lrwxrwxrwx 1 juan juan 3 abr 21 15:26 lib64 -> lib
drwxr-xr-x 2 juan juan 4096 abr 21 15:26 media
drwxr-xr-x 2 juan juan 4096 abr 21 15:26 mnt
drwxr-xr-x 2 juan juan 4096 abr 21 15:26 opt
drwxr-xr-x 4 juan juan 4096 abr 22 16:29 pkg-binpkgs
drwxr-xr-x 2 juan juan 4096 abr 28 12:09 pkg-builddir
drwxr-xr-x 1020 juan juan 40960 abr 28 12:09 pkg-destdir
drwxr-xr-x 2 juan juan 4096 abr 28 01:46 pkg-srcdistdir
drwxr-xr-x 2 juan juan 4096 abr 26 05:29 proc
drwxr-x--- 2 juan juan 4096 abr 21 15:26 root
drwxr-xr-x 2 juan juan 4096 abr 28 12:09 sbin
drwxr-xr-x 2 juan juan 4096 abr 26 05:29 sys
drwxrwxrwt 3 juan juan 12288 abr 28 12:09 tmp
drwxr-xr-x 3 juan juan 4096 abr 22 06:19 tools
drwxr-xr-x 10 juan juan 4096 abr 26 21:51 usr
drwxr-xr-x 14 juan juan 4096 abr 28 00:45 var
[juan@nocturno ~]$

[juan@nocturno ~]$ ls -l /storage/masterdir/pkg-destdir/dash-0.5.5.1/
total 28
drwxr-xr-x 2 juan juan 4096 abr 22 12:22 bin
-rw-r--r-- 1 juan juan 399 abr 22 12:22 files.plist
-rwxr-xr-x 1 juan juan 690 abr 22 12:22 INSTALL
-rw-r--r-- 1 juan juan 590 abr 22 12:22 props.plist
-rwxr-xr-x 1 juan juan 689 abr 22 12:22 REMOVE
drwxr-xr-x 3 juan juan 4096 abr 22 12:22 usr
drwxr-xr-x 3 juan juan 4096 abr 22 12:22 var
[juan@nocturno ~]$

[juan@nocturno ~]$ ls -l /storage/masterdir/bin/dash
lrwxrwxrwx 1 juan juan 34 abr 22 12:22 /storage/masterdir/bin/dash -> /pkg-destdir/dash-0.5.5.1/bin/dash
[juan@nocturno ~]$

xbps-src allows you to unstow (remove its symlinked files from the masterdir, and unregister package from the package database), as well as stowning the package multiple times, the only requirement is that the package must be installed into its destdir (destination directory), acomplished with the 'xbps-src install-destdir' command.

You can see the source code for the three C small programs here (yes, they are in the public domain): chroot.c, mount.c, umount.c.

Some more improvements were made but I'll explain (perhaps) them in another post... enjoy it.

XBPS Library API documentation

Two months ago I started working in documenting the XBPS library API with doxygen and graphviz. It took me 1 week of work to properly document the modules and create the graphs of the plist files and its dictionaries.

Yesterday I uploaded it to the XBPS server, and here are the results:

http://xbps.nopcode.org/doc/api/html/

Please note that the API is still not finished and I could change in the future, and probably adding more high level functions to acomplish specific tasks. In the meanwhile, I've updated the XBPS main page with notes, tables, etc. Enjoy it!

Tuesday, April 20, 2010

Portable proplib: rw support for gzipped plist files


Today I released version 0.4.1 of the Portable proplib implementation, that is used extensively in XBPS for package metadata, package databases and repository metadata. This new version implements support for reading and writting from/to compressed gzip files with zlib.
The ABI remains compatible and the API has been modified with the
following functions for this task:


prop_{array,dictionary}_internalize_from_zfile():
Internalizes a compressed or uncompressed plist file.


prop_{array,dictionary}_externalize_to_zfile():
Externalizes an array/dictionary into a compressed gzip plist file.


The _zfile variants of these functions support gzip and uncompressed files, so you can safely always use the them and support both types of files.

The following source code in C internalizes a plist file (compressed or uncompressed),
externalizes the result into a compressed file (if argv[1] == 'ext') and prints
the number of objects in the dictionary. If argv[1] == 'int' it's not externalized.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <prop/proplib.h>

int main(int argc, char **argv)
{
char path[256];
prop_dictionary_t d;

if (argc != 3)
exit(EXIT_FAILURE);

/* Externalize a plist file into a gzipped file */
if (strcmp(argv[1], "ext") == 0) {
d = prop_dictionary_internalize_from_zfile(argv[2]);
snprintf(path, sizeof(path), "%s.gz", argv[2]);
prop_dictionary_externalize_to_zfile(d, path);

/* Internalize a gzip plist file */
} else if (strcmp(argv[1], "int") == 0) {
d = prop_dictionary_internalize_from_zfile(argv[2]);
fprintf(stderr, "%s", prop_dictionary_externalize(d));
}
fprintf(stdout, "Total objs in dictionary: %u\n",
prop_dictionary_count(d));

exit(EXIT_SUCCESS);
}

I got two files, one compressed and another one uncompressed with the same
dictionary (and data) on them:

[juan@nocturno test]$ file pkgidx.plist*
pkgidx.plist: XML document text
pkgidx.plist.gz: gzip compressed data, from Unix, max compression
[juan@nocturno test]$

Now running the example code and redirecting stderr output to /dev/null
(which is too large to show) is able to read the data automagically:

[juan@nocturno test]$ time ./a.out int pkgidx.plist.gz 2>/dev/null
Total objs in dictionary: 3

real 0m0.041s
user 0m0.038s
sys 0m0.002s
[juan@nocturno test]$ time ./a.out int pkgidx.plist 2>/dev/null
Total objs in dictionary: 3

real 0m0.033s
user 0m0.029s
sys 0m0.003s
[juan@nocturno test]$

We can use the 'ext' argument to the example code to magically convert
a non compressed plist file into a compressed gzip file, like:

[juan@nocturno test]$ rm pkgidx.plist.gz
[juan@nocturno test]$ time ./a.out ext pkgidx.plist 2>/dev/null
Total objs in dictionary: 3

real 0m0.111s
user 0m0.096s
sys 0m0.005s
[juan@nocturno test]$
[juan@nocturno test]$ ls -l pkgidx.plist*
-rw-r--r-- 1 juan juan 1009406 abr 20 15:22 pkgidx.plist
-rw-r--r-- 1 juan juan 130546 abr 20 15:49 pkgidx.plist.gz
[juan@nocturno test]$

The portable proplib implementation, maintained by myself, is available from
http://code.google.com/p/portableproplib and will be used in the upcoming XBPS version 0.5.

Saturday, April 17, 2010

XBPS: bootchart with GNOME

So here are the results of running bootchart in a GNU/Linux system built with XBPS, on a GNOME desktop system. Please note that this can be improved vastly if I change ntpd, and other services to be started later, but I don't really care... the chart is only here to compare with other distributions (hi Ubuntu!).

The results indicate that it took 22 seconds to start (even with the password prompt) to be in the user desktop system; probably next time I should enable autologin and compare. Really, 22 seconds is fucking great for a system built for home use!

Thursday, April 15, 2010

XBPS: working in GNOME 2.30, xorg-server-1.8.0 ready...

Long time without posting to the blog, but really I have stuff to do everyday much like every other person in the world. So much stuff happened over this time that I cannot remember, but briefly, XBPS is currently at version 0.4.1 and the number of available packages and quality of the build system has improved vastly.

Long ago I added support to build packages in a chroot (with xbps-src) without root privileges; this works thanks to Linux supporting POSIX File capabilities. You still need root permissions to be able to bind (or null in BSD world) mount some directories. This is the only step requiring the permission and it's all encapsulated in a small shell script.

I've been working for the past days in bringing GNOME 2.30 to XBPS, there are zillions of dependencies as you might already know, but it's really progressing. The number of packages in XBPS has increased vastly for these months:

[juan@nocturno srcpkgs]$ find . -type f -name \*template|wc -l
1121
[juan@nocturno srcpkgs]$

Every template file results in a binary package. Some highlights include latest Xorg (with the xorg-server-1.8.0 that doesn't need HAL and uses UDEV), latest stable and main (HEAD in BSD world) kernel, latest XFCE, latest GNOME (a minimal desktop, not fully finished), etc.

I wanted to show everyone some mandatory screenshots of GNOME running in XBPS (really I should give the distribution a name, but every time I think about it I'm out of ideas)... enjoy.