Developer Chroots Utility Guide
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!
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-2.5 license. The Gentoo Name and Logo Usage Guidelines apply.
|