Skip to content

Instantly share code, notes, and snippets.

@adamhooper
Created December 7, 2019 18:56
Show Gist options
  • Save adamhooper/a396eed15e7bcb67b8da35a78271d366 to your computer and use it in GitHub Desktop.
Save adamhooper/a396eed15e7bcb67b8da35a78271d366 to your computer and use it in GitHub Desktop.
Build a 20GB-or-less chroot layer
#!/bin/bash
set -e
CHROOT=/var/lib/workbench/chroot # Empty
BASE_LAYER=/var/lib/workbench/chroot-base # already populated with /etc, /lib, /usr...
CHROOT_SIZE=20G # max size of user edits
VENV_PATH="/root/.local/share/virtualenvs" # only exits in dev
# /app/common (base layer)
# We copy the dir at runtime, not build time, because that's compatible with
# both dev and production.
mkdir -p $BASE_LAYER/app
cp -a /app/common $BASE_LAYER/base/app/
# Build upperfs.ext4 and mount it
# What's upperfs.ext4? It's a space-limited filesystem. If users write data
# larger than $CHROOT_SIZE to the chroot filesystem, they'll get
# "out of disk space" errors. We build a sparse file (`truncate`) to make this
# script super-fast on producion. (We don't care much about FS speed. The
# intended use case is large tempfiles and no fsync. When files grow beyond
# the Linux I/O cache size, users should expect slowdowns.)
mkdir -p $CHROOT/upperfs
truncate --size=$CHROOT_SIZE $CHROOT/upperfs.ext4 # create sparse file
mkfs.ext4 -q -O ^has_journal $CHROOT/upperfs.ext4
if ! mount -o loop $CHROOT/upperfs.ext4 $CHROOT/upperfs; then
# Docker without --privileged doesn't provide a loopback device. This affects
# dev mode (which we don't care about). But it should never happen on production.
echo "******* WARNING: failed to mount loopback filesystem $CHROOT/upperfs *****" >&2
echo "We will not constrain chrooted disk usage. If untrusted code writes" >&2
echo "too much to disk, the system will exhibit undefined behavior." >&2
fi
# Build overlay filesystem, with upper layer on upperfs
mkdir -p $CHROOT/upperfs/{upper,work}
mkdir -p $CHROOT/root
mount -t overlay overlay \
-o dirsync,lowerdir=$BASE_LAYER,upperdir=$CHROOT/upperfs/upper,workdir=$CHROOT/upperfs/work $CHROOT/root
# Now, `chroot /var/lib/workbench/chroot/root` will enter the chroot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment