· about 30 minutes · runs on ubuntu-26.04-devops · unrated
An unrated lab. It runs on your machine with no account and no network, and everything about it — the faults, the checks, the hints and the reference solution — is in the repository. An attempt on it is recorded on your profile and never moves a rating: only rated labs do. Rated and unrated labs.
The web server serves whatever /srv/www/current points at. Releases are unpacked next to it, in
/srv/www/releases/, by deploy-site:
deploy-site /tmp/release-2026-09-13.tar.gz
Last night a release archive arrived truncated. deploy-site printed deployed, exited 0, and the
site served an empty directory until someone noticed in the morning. The on-call engineer also says
the script "does something strange" when it is run twice quickly, and that it failed outright on the
staging box, where the web root is /srv/web root/ — with a space.
What is expected, and graded — the grader runs deploy-site itself, against its own directories,
through the SITE_ROOT variable the script already reads:
SITE_ROOT contains spaces.current still points at the previous release, no
half-unpacked release is left behind, and the script exits non-zero.current ends on the
second.You have root through sudo. Everything must still hold after a reboot.
The machine is checked, rebooted, and checked again. A check passes only if it passes both times.
| Check | Objective |
|---|---|
| 01_good_release_goes_live | Quote paths so that a directory with spaces works |
| 02_bad_release_changes_nothing | Stop a script at the first failure and report it with a non-zero exit status |
| 03_no_argument_changes_nothing | Stop a script at the first failure and report it with a non-zero exit status |
| 04_two_deploys_in_a_row | Switch a release atomically, and keep every release in its own directory |
Where the lab's hints send you, level by level, as you ask for them (h, then l opens a journal section in the TUI).
4 questions on the same topic, in the lab's Theory tab. They never affect the lab's grade. Three of them, to answer here:
What does this print?
f() { false; echo "after"; }
f
echo "status=$?"
after status=0
Without set -e, a failing command does not stop a function, and a function's status is that of its last command — echo, which succeeds. The two lines are joined by a space in the answer. A caller cannot learn about the failure unless the function returns it.
man 1 bash (FUNCTIONS; EXIT STATUS) · executed in a sandbox
A symlink `current` points to the directory `releases/a`. What does `ln -sf releases/b current` do?
Creates a link named b inside releases/a and leaves current unchanged
ln follows a link to a directory when it is the last argument and creates the new link inside that directory. -n (--no-dereference) treats current as a file to replace, which is what a deploy switch needs.
man 1 ln
Why is `ln -sfn new .tmp && mv -Tf .tmp current` preferred to `rm current && ln -s new current` for a live switch?
rename(2) replaces current in one step, so there is never a moment with no link
rm followed by ln leaves a gap during which requests find no content, and if ln fails the gap is permanent. A rename within one filesystem is atomic; -T stops mv from moving the new link into the directory current points to.
man 2 rename · man 1 mv