Exercise

A Robust Sync Service Exercise

Task

Synchronize /etc from servera to workstation when that host is reachable, and fail visibly when it is not. A sync that did not happen is a problem, and systemd will remember it as one.

Hosts
servera and workstation
Sync
/etc to /tmp/etc_from_servera
Runs as
root
Must fail when
workstation is unreachable
  1. Write the sync script

    Become root and install rsync, which servera does not have. Remember that rsync must exist on both ends.

    sudo -i
    dnf install -y rsync

    Write the script with a proper hashbang and its settings as variables, so the host and destination are named once.

    vim /usr/local/bin/etc_sync.sh
    #!/bin/bash
    TARGET_HOST="workstation"
    TARGET_DIR="/tmp/etc_from_servera"
    
    rsync -a --delete /etc/ "${TARGET_HOST}:${TARGET_DIR}/"

    Make it executable and run it once by hand. Never hand systemd a command you have not run yourself.

    chmod a+x /usr/local/bin/etc_sync.sh
    /usr/local/bin/etc_sync.sh
    ssh workstation 'ls /tmp/etc_from_servera | head -3'
  2. Write a service unit for it

    A service unit says how to run something. This one adds a condition that is checked before every run.

    vim /etc/systemd/system/etc-sync.service
    [Unit]
    Description=Sync /etc to workstation
    
    [Service]
    Type=oneshot
    ExecStartPre=/usr/bin/ping -c1 -W2 workstation
    ExecStart=/usr/local/bin/etc_sync.sh

    Tell systemd to re-read the unit files.

    systemctl daemon-reload
  3. Start it and read the journal

    Start the unit by hand and look at what systemd recorded.

    systemctl start etc-sync.service
    systemctl status etc-sync.service --no-pager
    journalctl -u etc-sync.service -n 10 --no-pager
  4. Break the check and watch the unit fail

    Point the check at an address that does not answer.

    vim /etc/systemd/system/etc-sync.service

    Search for the line with /ExecStartPre, press C to replace it from the cursor to the end of the line, and type:

    ExecStartPre=/usr/bin/ping -c1 -W2 192.0.2.99

    Reload and start it again.

    systemctl daemon-reload
    systemctl start etc-sync.service
    echo "exit status: $?"
    systemctl is-failed etc-sync.service
    journalctl -u etc-sync.service -n 5 --no-pager

    The start command exits 1, the unit reports failed, and ExecStart never ran. Now ask systemd what is broken on this machine.

    systemctl --failed
  5. Restore the check

    Put the reachable host back, so the service works for the next exercise.

    vim /etc/systemd/system/etc-sync.service

    Search with /ExecCondition, replace the line with C:

    ExecStartPre=/usr/bin/ping -c1 -W2 workstation
    systemctl daemon-reload
    systemctl start etc-sync.service
    systemctl is-failed etc-sync.service
    systemctl --failed