chroot-install - An aid to packaging
chroot-install [-achmnsvDLSF] [-V level] [-R root_dir] [-r project_root] [-p prototype] [-u user] [-g group] [-U uid] [-l dir[:dir ...]] [-d dir[:dir ...]] [-x dir[:dir ...]] [-e file -E checksum] [-C c[opy]|m[ount]|n[one]] [-P c[opy]|m[ount]|n[one]] [-M file] [-Y file] [command] [arg ...]
This script is designed to setup and then tear down an environment suitable for chroot()ing into where a program can be installed. In this way everything the installation process performs can be tracked.
It should be noted that due to the use of the chroot() system call
this script will require root privilages. If the script is run by
a non-root user then su will be invoked to gain root
privilages.
Supported options are:
chroot-install [-achmnsvDLSF] [-V level] [-R root_dir] [-r project_root] [-p prototype] [-u user] [-g group] [-U uid] [-l dir[:dir ...]] [-d dir[:dir ...]] [-x dir[:dir ...]] [-e file -E checksum] [-C c[opy]|m[ount]|n[one]] [-P c[opy]|m[ount]|n[one]] [-M file] [-Y file] [command] [arg ...]
More details on the options are shown below
The following options are related to how the chroot() environment
is setup and configured.
chroot() environment.
The option has to be one of the following:
+--------+--------+--------------------------------+ | Option | Abrev. | Action | +--------+--------+--------------------------------+ | copy | c | Copy the directory | | mount | m | Read-only mount the directory | | none | n | Not provided | +--------+--------+--------------------------------+
The default is ``m'', i.e. to mount the directory. If
you are installing a perl module you will have to
use -P copy which results in a large performance hit
as the perl environment is copied into the chroot()
environment.
chroot() environment.
The option has to be one of the following:
+--------+--------+----------------------+ | Option | Abrev. | Action | +--------+--------+----------------------+ | copy | c | Copy the directory | | mount | m | Mount the directory | | none | n | Not provided | +--------+--------+----------------------+
The default is ``m'', i.e. to mount the directory.
It should be noted that in this case the loopback mount
of the directory is done on a read/write basis rather than
a read-only basis. This means that any changes which occur
inside the chroot()ed environment will be reflected
outside it as well.
$PWD -> The current working directory of the
script
$USER -> The username of the person running the
script
o /usr/local o /usr/local/bin o /usr/local/man o /usr/local/lib o /usr/local/include
This is most useful for installation scripts which assume that the installation directories already exist so they don't need to create them; this is a depressingly frequent occurance as well.
-r flag, this moves the contents
of the project root to the top of the project root.
It ensures that only files within the project root exist; if this is not the case then it will cause a fatal error.
chroot() area by loopback file
system (i.e. lofs(7FS))
chroot() area.
chroot() area. Note that if the file name does
not have a full directory path it is considered to be a
command name.
filename mode
Where the filename is relative to the root directory
/etc/passwd and
/etc/group files within the chroot() area are recorded.
The file has the following format:
FILE line
Where FILE is either passwd or group. line is the
actual changed line from the file. It should be noted that only
additions to the file are tracked.
This option is primarily used by build-pkg.
chroot()ed environment
The following options provide helpful features which may not be required in day-to-day usage of this script.
-p)
-s (strip setuid/setgid/save
text) will ensure that all files are forced to
this user.
-s (strip setuid/setgid/save
text) will ensure that all files are forced to
this group.
The following options provide information about the running of this script
-V 2
most - Enable most messages (equivalent is -V 5) all - Enable all messages
The following options are useful in debugging the script and should not be required in day-to-day usage of this script.
-V all
The following options are used internally by the script if it
has to call itself again using su. They are only
listed here for informational usage; it is not expected that
they are used by end users.
su has to be called.
-E flag. This option is used internally by
the script and should not be used by users.
This script builds an environment suitable for a chroot()ed environment
by doing the following:
IN_CHROOT_INSTALL to the value of ``yes'' so
that scripts et al can tell if they are being run within a chroot-install
provided environment.
root user so that the chroot() can be
performed. If the script is not running as the root user then it will gain
root privilages by the use of su.
chroot() environment as required. This can involve:
/usr/lib/ld.so.1, via loopback
mounts i.e. using the lofs file system.
chroot() jail so that it appears as though you are within the same
directory before and after the chroot() has occured.
umask) to 022 so that
files and directories are created with sane permissions.
chroot() environment.
chroot() environment, only leave behind the files which have
been installed or changed by the commands run within it.
prototype file
Whilst this may appear to be a large amount of work the result is that it
appears to the installation
process occuring within the chroot() jail that it has access to the entire
system can do what it wants.
This is due to chroot() changing the root directory of the process which
calls the chroot() system call. Every process has a pointer to the
physical directory the root file system, or / resides on. This pointer
is used in all file handling operations where the system is called upon
to find the location of /. Thus to open the file /somefile the
system will do something similar to the following:
somefile
somefile exists then get its inode, open it and then
return back the open file handle
This means that if the pointer for / in a process is changed to
a different directory then the entire world view of the process will
be changed.
This is what the chroot() system call does.
Due to this world view change, a working environment has to be built
for the chroot()ed process as essential system files will not be
present within the new world view the process has.
So if the following lines of code were executed:
chdir("/some/directory");
chroot("/some/directory");
Then the root directory for the calling process would stop being / and
start being /some/directory. Effectively this would mean that chdir("/")
would actually take you to /some/directory.
This does cause some problems as there are files which are essential to the
sane running of the system. For example if you wanted to run the most basic
shell, /bin/sh in a chroot()ed environment, you'd have to provide at
least the following inside the directory the process was going to be
chroot()ed to:
/bin/sh
/usr/ld.so.1
/dev/zero
/usr/lib/libc.so.1
/usr/lib/libdl.so.1
/usr/lib/libw.so.1
/usr/lib/libintl.so.1
The script, whilst having a large number of command line options, is relatively simple to use. In the simplest case all you need to do is use:
% chroot-install
And the following will be displayed; note the asking of the root password for
gaining root privilages by using su. This is only done if you do not already
have root privilages.
chroot-install: You have to be root to run this command
Password:
chroot-install: Creating /home/simes/work/install
chroot-install: Setting environment variables
chroot-install: Creating directories
chroot-install: Copying file
chroot-install: Ensuring certain commands exist
chroot-install: Building devices
chroot-install: Working on copying directories
chroot-install: Working on mounting via lofs
chroot-install: Working on mounting via lofs
chroot-install: No command line arguments - spawning a shell
chroot-install: chroot()ing to /home/simes/work/install
chroot-install: You are chroot()ed, you will be limited in what you can do
root@host[1]%
At this point you can then type commands in as normal, although as the message above
says, since you are chroot()ed there will be limits as to what you can do. When
you exit the shell above the script will then clean up what it created:
root@yardie[1]% exit
chroot-install: Cleaning up random files
chroot-install: Unmounting lofs
chroot-install: Removing copied directories
chroot-install: Removing devices
chroot-install: Removing specific commands
chroot-install: Removing files
chroot-install: Removing directories
chroot-install: Cleaning up after CreateDir()
Whatever was done in the chroot() jail will be held in the directory $PWD/install,
although this can be changed by the -R option.
One of the more useful command line options is -r which allows you to specify a
project root. This then creates not only that directory, but the directories
bin, man, lib and include under it. This is very useful for packages
who have what could be best described as naive installation scripts which assume
that such project roots exist on the machine already.
You can also give the script a command with arguments to run inside the chroot()
jail instead of a shell. For example:
% chroot-install make install
Would result in make install being run inside the chroot()ed environment.
For the full list of command line arguments, please run:
% chroot-install -h
IN_CHROOT_INSTALLyes'' so that scripts run from within an environment
provided by chroot-install can tell that they are within said environment.
There are issues with the use of this program with NFS mounted directories.
Since the majority of the work performed by this program is done as the
root user the default options for NFS serving will break this program.
By default the root user (i.e. UID 0) has the same privilages
the nobody user (actually takes the UID of the nobody user) when
accessing an NFS mounted directory unless the NFS server has been configured
not to do this.
As a result of this it is recommended that this program is not used on
a directory which is mounted via NFS unless the NFS server has been
configured to give the root user the privilages of the root user
on the NFS server.
You need to have the system provided version of perl (installed at /usr/perl5)
available
It is not possible to provide software from within the area being installed
into by loopback mount. For example, the installation process of some
software requires the command some-prog which has been installed under the
/usr/local/ tree. Now, if the software in question is also to be installed
under the /usr/local/ tree we have a problem. It is not possible to just
loopback mount the /usr/local/ directory as this would make the directory
tree you are attempting to install under read-only and thus prevent the
installation of the package from occuring. It may also not be sensible to
copy all of the /usr/local/ tree into the chroot() environment; on most
systems this would add a large amount of time to the package building
process.
The only real solution is a kludge; you avoid the use of chroot-install by
having the software package install in the InstallPackage/build directory
as described in the manual page for build-pkg. For example with software
which uses GNU autoconf this could mean doing the following:
make prefix=`pwd`/InstallPackage/build/usr/local install
However this also means that you have to check the Makefile of the software
to ensure that it does not install anything outside of the prefix tree.
Simon Burr <simes@bpfh.net>
Copyright (c) 2002, Simon Burr <simes@bpfh.net> All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.