Manage Chroot Environments with Schroot

Schroot allows users to switch between different Linux distributions or releases conveniently. As a software developer, I have to test software between different Debian and Ubuntu releases. Schroot perfectly fits my use case.

Besides, schroot has good balance between isolation and convenience. By default, it will mount the home directory in the chroot environment so that files are shared between the host and the chroot environment. In addition, after configuring chroots, users don't need root privileges to enter a chroot. These features significantly streamline my day-to-day software development process.

As a daily user of schroot, I feel that I must write an article to introduce schroot to all software developers. This article is a gentle introduction to schroot. It covers the basic usages of the schroot command.

There are 4 sections in this article:

  • Installation section covers the instructions to install schroot and debootstrap.
  • Set Up a Chroot section covers the instructions to prepare a root file system with debootstrap and create a schroot configuration file.
  • Enter a Chroot Environment section covers the basic usage of the schroot command.
  • Manage Sessions section describes how to start a schroot session, list schroot sessions, enter a schroot session, and end a schroot session.7

Installation

To install schroot on Debian or Ubuntu, run the command below:

$ sudo apt-get install schroot

It is recommended to install debootstrap as well:

$ sudo apt-get install debootstrap

Set Up a Chroot

There are two steps to setup a chroot environment. First, we have to prepare a root file system, which will become the new root directory / while running the schroot command. And then, we have to create a configuration file for the schroot command. Let's start from the first step.

Prepare a Root File System

A root file system consists of utility commands, shared libraries, system configuration files, etc. It requires some expertise if you would like to craft a root file system manually. Linux distributions usually have some mechanisms to automate the process. For Debian and Ubuntu, you may create a root file system with the debootstrap command.

For example, to create an Ubuntu 16.04 (Xenial Xerus) root directory at /var/chroot/xenial, run the command below:

$ sudo debootstrap xenial /var/chroot/xenial \
    http://archive.ubuntu.com/ubuntu

If you would like to run a 32-bit chroot on an x86-64 host, run debootstrap --arch=i386:

$ sudo debootstrap --arch=i386 xenial /var/chroot/xenial32 \
    http://archive.ubuntu.com/ubuntu

If you would like to run a chroot with QEMU (such as running an arm64 chroot on an x86-64 host), refer Introduction to qemu-debootstrap for further information.

Create a Configuration File

After setting up a root file system, we have to create a schroot configuration file in /etc/schroot/chroot.d.

For example, open a configuration file with:

$ sudo editor /etc/schroot/chroot.d/xenial.conf

And fill in the configuration (remember to substitute USERNAME with your user name):

[xenial]
description=Ubuntu 16.04 Xenial Xerus
directory=/var/chroot/xenial
root-users=USERNAME
users=USERNAME
type=directory

The configuration file consists of a chroot name (wrapped by a pair of square brackets) and several properties:

  • directory -- The root directory of the chroot environment.
  • users -- A comma-separated list of the users that have access to the chroot environment.
  • root-users -- A comma-separated list of the users that can get root privileges in the chroot environment by specifying -u root.
  • type -- This can be either directory or plain.
    • If directory is specified, the home directory will be mounted in the chroot environment. In most cases, directory is a convenient and the suggested option.
    • If plain is specified, schroot won't run any setup scripts.
  • personality -- The personality of the chroot environment. To run a 32-bit chroot environment on a x86-64 host, set personality to linux32.

After creating the configuration file, schroot -l should list the chroot environments that are available:

$ schroot -l
chroot:xenial

Note

Schroot configuration files must be owned by root and must not be writable by other users.

Enter a Chroot Environment

Now, it's time to enter a chroot environment with the schroot command.

To enter a chroot environment, run schroot -c [name]:

$ schroot -c xenial
(xenial)user@hostname:~$

To leave a chroot environment, type exit:

(xenial)user@hostname:~$ exit
$

To execute a command in a chroot and leave a chroot after the command completes, append -- and the command to be executed. For example, to execute the cat /etc/lsb-release command in the chroot environment, run the command below:

$ schroot -c xenial -- cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"
$

To enter a chroot with root privileges, append -u root to the command line:

$ schroot -c xenial -u root
(xenial)root@hostname:/home/user#

Manage Sessions

The simpliest schroot -c command mentioned in the previous section starts an automatic session before running the command and ends the automatic session after the command completes. When a session starts, schroot will mount the file systems and execute the start hooks. When a session ends, schroot will execute the exit hooks and unmount the file systems. It may be time consuming if you have to enter and leave a chroot several times.

Under some circumstances (e.g. running several unit tests with schroot), it would be great to manage sessions manually. This section covers the command to start a session, list sessions, enter a session, and clean up a session.

Start a Schroot Session

To start a schroot session, run schroot -b -c [name]:

$ schroot -b -c xenial
xenial-05735790-a1ab-464b-8675-4e66111370d3

The schroot command will print the session name to the standard output. To keep the session name in an environment variable, run this command instead:

$ SESSION="$(schroot -b -c xenial)"

You may specify a session name with -n [session-name] as well:

$ schroot -b -c xenial -n mysession
mysession

List All Schroot Sessions

To list all schroot sessions, run schroot -l --all-sessions:

$ schroot -l --all-sessions
session:xenial-05735790-a1ab-464b-8675-4e66111370d3

Enter a Schroot Session

To enter a schroot session, run schroot -r -c [session-name]:

$ schroot -r -c xenial-05735790-a1ab-464b-8675-4e66111370d3
(xenial)user@hostname:~$

This is similar to the simpliest schroot -c command mentioned earlier. You may append command to be executed or specify -u root for root privileges.

End a Schroot Session

To end a schroot session (i.e. unmount all file systems and execute the exit hooks), run schroot -e -c [session-name]:

$ schroot -e -c xenial-05735790-a1ab-464b-8675-4e66111370d3

BTW, if the computer reboots before the simpliest schroot -c completes, the automatic session won't be ended. To clean up those sessions, you have to find their names with schroot -l --all-sssions and end those sessions with schroot -e -c [session-name].