[ norboten ]
python · lab python-01

The Sync That Says It Worked

· 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 briefing

/opt/sync/sync.py copies the inventory records from the internal inventory API into /var/lib/sync/records.json, which three other services read. sync.timer runs it shortly after boot and every five minutes after that.

On Monday the dashboards showed zero machines for an hour. The sync's journal said done: 0 records every five minutes, and systemd listed every run as successful. On Wednesday the API was slow to answer and the job was still "running" at lunchtime, so no later run could start.

The API itself is records-api.service. It should answer on http://127.0.0.1:8901/records.

What is expected, and graded — the grader runs sync.py itself, with its own test servers, through the SYNC_API and SYNC_OUTPUT variables the script already reads:

  1. When the API answers with an error, the script exits non-zero and leaves the existing output file exactly as it was.
  2. When the API accepts a connection and never answers, the script gives up and exits non-zero within 15 seconds.
  3. A good run exits 0 and replaces the output in one step, so a reader never sees a half-written file.
  4. The run started by sync.timer succeeds and writes the API's records, and still does after a reboot.

You have root through sudo.

What is graded

The machine is checked, rebooted, and checked again. A check passes only if it passes both times.

CheckObjective
01_api_error_is_a_failureTurn errors into a non-zero exit status instead of a false success
02_stalled_api_times_outPut a timeout on every network call
03_good_run_replaces_the_fileReplace a data file atomically, and never overwrite good data with nothing
04_timer_run_succeedsRun a job from a systemd timer with the right configuration

Start it

  1. 2Labs
  2. python-01select this one
  3. udownload it
  4. sstart the machine

Reading

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).

Theory for this lab

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:

Question 1

What does this print?

import subprocess, sys
code = "def main():\n    return 3\nmain()"
print(subprocess.run([sys.executable, "-c", code]).returncode,
      subprocess.run([sys.executable, "-c", "import sys\nsys.exit(3)"]).returncode)
Question 2

What does this print?

import json, socket, urllib.error
print(issubclass(urllib.error.HTTPError, OSError),
      issubclass(TimeoutError, OSError),
      issubclass(json.JSONDecodeError, ValueError))
Question 3

What does this print?

import os, tempfile
d = tempfile.mkdtemp()
path = os.path.join(d, "data.json")
open(path, "w").write("old")
before = os.stat(path).st_ino
fd, tmp = tempfile.mkstemp(dir=d)
os.write(fd, b"new"); os.close(fd)
os.replace(tmp, path)
print(os.stat(path).st_ino == before, oct(os.stat(path).st_mode & 0o777))