Gentoo Logo

Developer Chroots Utility Guide

Content:

1. Introduction

What is this all about?

The normal procedure for a developer setting up a chroot is to fetch a stage, find a directory where to unpack it, unroll the stage, make some modifications to basic files like /etc/resolv.conf, /etc/hosts and others. Then she or he is usually incorporating some kind of custom script to start the chroot again once the machine gets rebooted or she/he needs to reenter it for another reason. More advanced scripts use screen sessions for making the chroot command launching the chroot independent of the currently connected user.

However, lots of these scripts exist and people are using more and more chroots on our development servers, which is a very good thing in fact because it's relieving stress off the main system and is making our production systems more stable if development is done inside contained chroots.

There has been a previous version of devel-chroots, but the old version only had limited multiuser capabilities and was rather bulky compared to the code in the script and the configuration abilities of the different chroots.

For this reason, the new version of devel-chroots has been completely rewritten and is using a three-layered approach of configuration data for setting up chroots and populating the config files in these.

Finishing this introduction, this guide is not meant to be exclusive to Gentoo development machines and their maintainers and users, the tool has been developed to be usable on any machine where chroots should be set up in an automatic and configurable fashion.

Your input is welcome and there is always room for improving this little program as it aims at easing development and promotes thorough regression and live testing by providing an easy way of setting up a testbed, which a chroot basically is.

2. Installation

Ebuild installation

The utility can be emerged with the following shell command:

Note: If you want to emerge only the basic tool without the sample configuration, activate the "minimal" USE-flag.

Code Listing2.1: Installation of devel-chroots

# USE="-minimal" emerge -pv devel-chroots

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R   ] dev-util/devel-chroots-2.0.0  USE="-minimal*" 0 kB 

Total size of downloads: 0 kB

# USE="-minimal" emerge -v devel-chroots

Code Listing2.2: Installation of devel-chroots without configuration files

# USE="minimal" emerge -pv devel-chroots

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R   ] dev-util/devel-chroots-2.0.0  USE="minimal" 0 kB 

Total size of downloads: 0 kB

# USE="minimal" emerge -v devel-chroots

Fetching the source code

The source code for the project can be found in the following anonymous cvs or svn location, along with viewcvs:

Code Listing2.3: fetching the project source code with anonymous cvs

/tmp/dc $ cvs -d :pserver:anonymous@anoncvs.gentoo.org/var/cvsroot co gentoo-projects

Code Listing2.4: fetching the project source code with anonymous svn

/tmp/dc $ svn co http://anonsvn.gentoo.org/repositories/gentoo-projects

Then dive into the gentoo-projects/devel-chroots/devel-chroots-2.0.0/ directory to see the source code for the project.

As you can see, it's just the same as the scripts that are getting installed by the ebuild. Which positively means that you can theoretically also use these scripts without having an ebuild install them.

3. Configuration

General machine configuration

There is no standard location where a stage3 file may be located on the mirrors. For this reason, it is highly advised to edit the default configuration file and explicitly set the STAGE_URL variable.

Code Listing3.1: STAGE_URL in default configuration

$ grep STAGE_URL /etc/devel-chroots/default/config
STAGE_URL="$(echo ${GENTOO_MIRRORS} | awk '{ print $1; }')/${STAGE_PATH}/${STAGE_NAME}"
# STAGE_URL="http://ftp.belnet.be/mirror/rsync.gentoo.org/gentoo/releases/x86/2006.0/stages/stage3-x86-2006.0.tar.bz2"

As you can see, the default mechanism is to pick the first mirror, add the stage path for a typical x86 stage and construct the name for a current profile's stage. However, this doesn't work for sparc for example, because they are differentiating between sparc32 and sparc64. The same holds true for hppa, where it's stages pertaining to the 1.1 ABI and the 2.0 ABI of different types of machines.

Also remember that users and specific chroots can always override this variable, so it would be the best thing to make sure it points to a reasonable default stable stage.

As said, users wishing to enable a hardened toolchain chroot, a linux32 chroot on an amd64 machine or a new bleeding edge stage from one of their private mirrors can always override this setting in their own config.

Another important piece of the configuration is the global make.conf. Basically, every single chroot contains a file /usr/local/chroot/conf.d/make.conf which is constructed from three possible make.conf files residing in the configuration directory of devel-chroots:

/etc/devel-chroots/default/make.conf is the main file for chroots.

/etc/devel-chroots/pappy/make.conf is holding user specific addons.

/etc/devel-chroots/pappy/chroot001/make.conf is a chroot specific file.

These three files make up the final /usr/local/chroot/conf.d/make.conf which then can be sourced by the real /etc/make.conf of the chroot.

User specific configuration

As noted in the previous section, each user can define her or his own versions of config and make.conf in the configuration directory /etc/devel-chroots/username. This enables the highest possible versatility and flexibility. For example, it is possible to allow a user define her or his own debugging settings for FEATURES and USE flags in make.conf.

Another example is the custom setting of the screenrc:

Code Listing3.2: user specific screenrc for chroot screen sessions

$ cat /etc/devel-chroots/pappy/screenrc
backtick 1 5 0 /home/pappy/bin/mem.sh
backtick 2 1 0 /home/pappy/bin/cetclock.sh 'CET' '-0200' '-0100'

hardstatus string '%{= kG}[%= %{= kw}%?%-Lw%?%{r}[%{W}%n*%f %t%?{%u}%?%{r}]%{w}%?%+Lw%?%?%= %{g}]%{W} %2`:%s %{g}%{.w}%H%{.c} [%l] %1`MB ram'

This makes it easy for users to include their own scripts in screen sessions of chroots, for example to measure disk usage or load of the system.

Code Listing3.3: Example: user specific CET date display on chroot screen

~ $ cat bin/cetclock.sh 
#!/bin/bash

# check for daylight saving time being currently active at this time
if [ "x$(perl -e '@timeData = localtime(time); print ${timeData}[-1];')y" == "x1y" ]
then
        date --utc --date="$(date --utc '+%F %T') $2" "+$1 %H:%M"
else
        date --utc --date="$(date --utc '+%F %T') $3" "+$1 %H:%M"
fi

Chroot specific configuration

Last but not least, on some arches (notably amd64), there is the possibility to install an x86 chroot using a special emulator command, called linux32. Redefining the respective variables in the chroot-specific /etc/devel-chroots/pappy/chroot001/config enables users to set up those special chroots on amd64 test machines:

Code Listing3.4: chroot specific config for linux32 chroot on amd64

$ cat /etc/devel-chroots/pappy/chroot001/config
CHROOT_BINARY="linux32 /usr/bin/chroot"
STAGE_URL="http://ftp.belnet.be/mirror/rsync.gentoo.org/gentoo/releases/x86/2006.0/stages/stage3-x86-2006.0.tar.bz2"

These variables are learned by the script and will be used for setting up the chroot. Other chroots are not affected by this setting, however. This makes it very easy for users to set up and maintain different chroots for their needs on the same machine at a time.

As you can see, in every case, chroot-specific data is overwriting default and user-specific data. Please do not change system-internal variables like the maximum number of chroots for a user and similar definitions inside a chroot-specific config file.

4. Startup and maintenance

Automatic startup

Automatic startup of the developer chroots is attained with an init script that is conforming to the Gentoo standards.

Code Listing4.1: starting the devel-chroots init script

# /etc/init.d/devel-chroots status
 * status:  stopped

# /etc/init.d/devel-chroots start 
 * Starting developer chroots for all users ...
 * pappy: starting chroot001 in (/space/devel-chroots/pappy/chroot001)
 * pappy: mounting chroot filesystems: /space/devel-chroots/pappy/chroot001
 * pappy: chroot001: creating conf: make.conf
 * pappy: starting chroot002 in (/space/devel-chroots/pappy/chroot002)
 * pappy: mounting chroot filesystems: /space/devel-chroots/pappy/chroot002
 * pappy: chroot002: creating conf: make.conf
 * config file [/etc/devel-chroots/pappy/chroot002/make.conf] not existing, skipping
 * no /etc/devel-chroots/pappy/chroot003 config dir
 * no /etc/devel-chroots/pappy/chroot004 config dir
 * no /etc/devel-chroots/pappy/chroot005 config dir
 * no /etc/devel-chroots/pappy/chroot006 config dir
 * no /etc/devel-chroots/pappy/chroot007 config dir
 * no /etc/devel-chroots/pappy/chroot008 config dir
 * launching detached screen session for pappy's chroots
 * remember that you have to source /usr/local/chroot/conf.d/make.conf
 * in the make.conf of created chroots for user-specific settings
 * for multiuser mode, you need to set /usr/bin/screen to mode 4755
 * and also change the directory /var/run/screen to mode 0755                                    [ ok ]

Code Listing4.2: restarting the chroots init script

# /etc/init.d/devel-chroots restart
 * Stopping developer chroots for all users ...
 * stopping chroot001 of user pappy (/space/devel-chroots/pappy/chroot001)
 * pappy: terminating the following screen sessions: 8638
 * pappy: unmounting chroot filesystems: /space/devel-chroots/pappy/chroot001
 * stopping chroot002 of user pappy (/space/devel-chroots/pappy/chroot002)
 * pappy: unmounting chroot filesystems: /space/devel-chroots/pappy/chroot002
 * no /etc/devel-chroots/pappy/chroot003 config dir
 * no /etc/devel-chroots/pappy/chroot004 config dir
 * no /etc/devel-chroots/pappy/chroot005 config dir
 * no /etc/devel-chroots/pappy/chroot006 config dir
 * no /etc/devel-chroots/pappy/chroot007 config dir
 * no /etc/devel-chroots/pappy/chroot008 config dir                                                                                           [ ok ]
 * Starting developer chroots for all users ...
 * pappy: starting chroot001 in (/space/devel-chroots/pappy/chroot001)
 * pappy: mounting chroot filesystems: /space/devel-chroots/pappy/chroot001
 * pappy: chroot001: creating conf: make.conf
 * pappy: starting chroot002 in (/space/devel-chroots/pappy/chroot002)
 * pappy: mounting chroot filesystems: /space/devel-chroots/pappy/chroot002
 * pappy: chroot002: creating conf: make.conf
 * config file [/etc/devel-chroots/pappy/chroot002/make.conf] not existing, skipping
 * no /etc/devel-chroots/pappy/chroot003 config dir
 * no /etc/devel-chroots/pappy/chroot004 config dir
 * no /etc/devel-chroots/pappy/chroot005 config dir
 * no /etc/devel-chroots/pappy/chroot006 config dir
 * no /etc/devel-chroots/pappy/chroot007 config dir
 * no /etc/devel-chroots/pappy/chroot008 config dir
 * launching detached screen session for pappy's chroots
 * remember that you have to source /usr/local/chroot/conf.d/make.conf
 * in the make.conf of created chroots for user-specific settings
 * for multiuser mode, you need to set /usr/bin/screen to mode 4755
 * and also change the directory /var/run/screen to mode 0755                                                                                 [ ok ]

As you can see, the init script is maybe generating lots of considered unnecessary output, however this is important for being able to judge why a certain chroot has not been set up and adds in easy understanding what is happening and what is not.

For example, as you can see, a chroot for a given user is only started if a configuration directory for that chroot could be found. It can be empty, but it has to exist for the given chroot to be started.

Please note that the usage of the init script should be left up to the discretion of the system administrator.

User management of chroots

Users should be issuing the following script for starting and stopping their own chroots:

Code Listing4.3: user maintenance of chroots: stopping chroots

$ sudo /usr/sbin/devel-chroots stop pappy
 * stopping chroot001 of user pappy (/space/devel-chroots/pappy/chroot001)
 * pappy: terminating the following screen sessions: 9371
 * pappy: unmounting chroot filesystems: /space/devel-chroots/pappy/chroot001
 * stopping chroot002 of user pappy (/space/devel-chroots/pappy/chroot002)
 * pappy: unmounting chroot filesystems: /space/devel-chroots/pappy/chroot002

Code Listing4.4: user maintenance of chroots: starting chroots

$ sudo /usr/sbin/devel-chroots start pappy  
 * pappy: starting chroot001 in (/space/devel-chroots/pappy/chroot001)
 * pappy: mounting chroot filesystems: /space/devel-chroots/pappy/chroot001
 * pappy: chroot001: creating conf: make.conf
 * pappy: starting chroot002 in (/space/devel-chroots/pappy/chroot002)
 * pappy: mounting chroot filesystems: /space/devel-chroots/pappy/chroot002
 * pappy: chroot002: creating conf: make.conf
 * launching detached screen session for pappy's chroots

Please remember there is no restart command:

Code Listing4.5: illegal use of restart command for chroot

$ sudo /usr/sbin/devel-chroots restart pappy
 * error: unknown mode: restart

Final notes

As noted in the init script, for users being able to reattach to root screen sessions as a user and use the acladd command to see who is working with them, it is necessary to change screen and the working directory of the screen session sockets.

However, this is a cosmetic advantage, because normally everybody is supposed to be root on a development system and there is no security restrictions.

But on the other hand, having a system of voluntarily least priviledges used for reconnecting to screen sessions as an authorized user never hurts, avoids mistakes and problems and opens up room for cutting down the necessary priviledges of scripts and users for having their work done!



Print

Page updated December 6, 2006

Summary: This guide covers the installation, configuration and set up of chroots using a tool developed for the Gentoo dev machines.

Alexander Gabert
Author

Donate to support our development efforts.

Copyright 2001-2012 Gentoo Foundation, Inc. Questions, Comments? Contact us.