norboten · cheat sheet

Your shell is not the environment — cheat sheet

python, boot-systemd
# the venv
/opt/etl/.venv/bin/python -c 'import sys, httpx; print(sys.prefix)'   # the venv is chosen by the EXECUTABLE
cat /opt/etl/.venv/pyvenv.cfg                    # what makes that symlink "the venv's python"
/opt/etl/.venv/bin/pip install -r requirements.txt    # dependencies go here, never into /usr
# activate = PATH + VIRTUAL_ENV + prompt. Not needed in units, cron or containers.

# a unit for a Python job
# [Service]
# Type=oneshot
# User=etl
# WorkingDirectory=/opt/etl                        (default for system units is /)
# ExecStart=/opt/etl/.venv/bin/python /opt/etl/report.py
# StateDirectory=etl                               (creates /var/lib/etl owned by etl)
# LoadCredential=token:/etc/etl/token              (→ $CREDENTIALS_DIRECTORY/token)
# NoNewPrivileges=yes  ProtectSystem=strict  ReadWritePaths=/var/lib/etl  PrivateTmp=yes
systemd-analyze security etl-report.service

# the timer
# [Timer] OnBootSec=5s  OnUnitActiveSec=5min      (monotonic: after boot, then after each run)
#         OnCalendar=*:0/5  Persistent=true        (wall clock; RandomizedDelaySec= on fleets)
# [Install] WantedBy=timers.target
systemctl enable --now etl-report.timer          # the TIMER; the service is static
systemctl list-timers --all etl-report.timer     # NEXT / LAST (a never-started timer is not listed)

# run it the way systemd runs it
systemctl start etl-report.service               # now, with the unit's real environment
systemd-run --wait --pipe -p User=etl -p WorkingDirectory=/opt/etl CMD   # try a config first
sudo journalctl -u etl-report.service -b -n 20 --no-pager
systemctl show -p Result -p ExecMainStatus -p User etl-report.service

# ownership
chown -R etl:etl /var/lib/etl                    # what it writes
chown etl:etl /etc/etl/token ; chmod 600 /etc/etl/token   # what only it reads
# code in /opt/etl: readable, NOT writable by the service account

# proving "unattended"
stat -c '%y' /var/lib/etl/reports/latest.json ; uptime -s    # report newer than the boot