Layanan kustom didefinisikan dengan berkas unit systemd, yaitu berkas teks berformat INI yang menjelaskan program apa yang dijalankan dan kapan unit itu diaktifkan. Topik ini membangun satu layanan pengarsip cadangan secara utuh, mulai dari skrip yang dipanggil, anatomi berkas unitnya, sampai pemeriksaan sintaks dengan systemd-analyze sebelum berkas itu dipasang. Skrip dan pemeriksaannya dieksekusi nyata di lingkungan latihan, sedangkan pemasangan akhirnya menuntut systemd yang berjalan.
Skrip yang dijalankan layanan#
Sebelum berkas unit ditulis, program yang akan dijalankan layanan harus sudah benar, karena systemd hanya mengeksekusi perintahnya tanpa memahami isinya. Layanan contoh pada topik ini adalah tugas sekali jalan (oneshot) yang mengarsipkan satu direktori menjadi arsip tar.gz. Direktori contoh yang menjadi sumber arsip disiapkan lebih dahulu:
# folder kerja dan contoh data yang akan dicadangkan
mkdir -p /tmp/kerja-berkas-unit/dokumen
printf 'catatan rapat mingguan\n' > /tmp/kerja-berkas-unit/dokumen/rapat.txt
printf 'daftar tugas\n' > /tmp/kerja-berkas-unit/dokumen/tugas.txt
printf 'bulan,jumlah\nJanuari,12\n' > /tmp/kerja-berkas-unit/dokumen/rekap.csv
ls -1 /tmp/kerja-berkas-unit/dokumenrapat.txt
rekap.csv
tugas.txtSkripnya bernama arsip-cadangan.sh dan menerima dua argumen, yaitu direktori sumber dan direktori tujuan. Kedua argumen diberi nilai default agar skrip tetap bisa dicoba tanpa argumen sebagaimana keluaran berikut:
#!/usr/bin/env bash
# arsip-cadangan.sh: membuat arsip cadangan tar.gz dari satu direktori
# Pemakaian: arsip-cadangan.sh [direktori-sumber] [direktori-tujuan]
SUMBER="${1:-/tmp/kerja-berkas-unit/dokumen}"
TUJUAN="${2:-/tmp/kerja-berkas-unit/cadangan}"
if [ ! -d "$SUMBER" ]; then
echo "Error: direktori sumber $SUMBER tidak ditemukan." >&2
exit 1
fi
mkdir -p "$TUJUAN"
NAMA="$(basename "$SUMBER")-$(date +%F).tar.gz"
tar -czf "$TUJUAN/$NAMA" -C "$(dirname "$SUMBER")" "$(basename "$SUMBER")"
JUMLAH="$(find "$SUMBER" -type f | wc -l)"
echo "Arsip cadangan selesai: $JUMLAH berkas diarsipkan ke $TUJUAN"Arsip cadangan selesai: 3 berkas diarsipkan ke /tmp/kerja-berkas-unit/cadanganSetiap barisnya memiliki peran yang jelas:
SUMBERdanTUJUANmembaca argumen pertama dan kedua, dengan tanda:-memberikan nilai default untuk percobaan tanpa argumen.- Percabangan
ifmenghentikan skrip dengan pesan error dan kode kembali satu apabila direktori sumber tidak ada, sehingga kegagalan tidak merambat ke langkah pengarsipan. mkdir -pmenyiapkan direktori tujuan beserta seluruh induknya sekali jalan.NAMAmenyusun nama berkas dari nama direktori sumber ditambah tanggal hari ini, sehingga arsip dari hari yang berbeda tidak saling menimpa.tar -czfmembuat arsip terkompresi, sedangkan opsi-Cmengubah direktori kerja agar isi arsip dimulai dari nama direktorinya, bukan dari jalur penuhnya.JUMLAHmenghitung berkas di dalam sumber denganfinddanwc -l, laluechomelaporkan ringkasannya sebagai bukti kerja.
Menguji skrip sebelum dipasang#
systemd memanggil ExecStart persis seperti pemanggilan program biasa, tanpa shell login dan tanpa terminal, sehingga skrip yang sudah benar di terminal hampir pasti benar pula di bawah layanan. Bukti ujinya sederhana, yaitu skrip disalin ke folder kerja, diberi izin eksekusi, lalu dipanggil dengan dua argumen eksplisit:
# menyalin skrip ke folder kerja lalu memberi izin eksekusi
cp arsip-cadangan.sh /tmp/kerja-berkas-unit/
chmod +x /tmp/kerja-berkas-unit/arsip-cadangan.sh
# memanggil skrip dengan dua argumen eksplisit
/tmp/kerja-berkas-unit/arsip-cadangan.sh /tmp/kerja-berkas-unit/dokumen /tmp/kerja-berkas-unit/cadanganArsip cadangan selesai: 3 berkas diarsipkan ke /tmp/kerja-berkas-unit/cadanganKeluarannya persis sama dengan percobaan tanpa argumen karena kedua argumen eksplisit menunjuk direktori yang sama dengan nilai defaultnya. Pada server sungguhan, skrip dipasang di /usr/local/bin, yaitu direktori untuk program buatan pengelola sistem, lalu diberi izin eksekusi yang sama.
Anatomi berkas unit#
Berkas unit layanan contoh bernama arsip-cadangan.service dan terbagi atas tiga bagian, yaitu [Unit] untuk metadata, [Service] untuk cara eksekusi, dan [Install] untuk aturan enable:
[Unit]
Description=Arsip cadangan direktori dokumen
[Service]
Type=oneshot
ExecStart=/usr/local/bin/arsip-cadangan.sh /srv/dokumen /var/backups/arsip
[Install]
WantedBy=multi-user.target- Bagian
[Unit]menyimpan metadata umum unit. BarisDescription=memberi keterangan singkat yang ditampilkansystemctl statusdan daftar unit. - Baris
Type=oneshotmenyatakan tugas sekali jalan yang dianggap selesai ketika prosesnya berakhir, berbeda dari layanan yang terus berjalan selama sistem menyala. - Baris
ExecStart=adalah perintah yang dieksekusi systemd. Jalurnya wajib absolut, dan argumen setelahnya diteruskan kepada program, sehingga baris ini memanggil skrip dengan direktori sumber dan tujuan pada server sungguhan. - Bagian
[Install]menentukan akibat perintah enable.WantedBy=multi-user.targetmembuat tautan unit di dalam direktori wants milik target tersebut, yaitu target standar server tanpa antarmuka grafis.
Untuk layanan yang tetap hidup, nilai Type= berubah menjadi simple atau forking sesuai cara program melepaskan dirinya dari pembuatnya, sedangkan bagian lainnya tetap sama. Kesederhanaan oneshot membuatnya cocok sebagai contoh belajar karena seluruh siklus hidupnya selesai dalam satu eksekusi skrip.
Memeriksa berkas unit dengan systemd-analyze#
Kesalahan pada berkas unit baru terasa ketika unit dipasang, kecuali diperiksa lebih dahulu. Perintah systemd-analyze verify membaca berkas unit tanpa menuntut systemd yang berjalan, sehingga pemeriksaan ini bisa dilakukan di mana saja. Berkas unit yang sah menghasilkan keluaran senyap dan kode kembali nol:
# unit paling sederhana yang sah untuk menguji systemd-analyze
printf '[Unit]\nDescription=Uji unit sah\n\n[Service]\nType=oneshot\nExecStart=/bin/true\n' > /tmp/kerja-berkas-unit/lulus.service
systemd-analyze verify /tmp/kerja-berkas-unit/lulus.service
echo "kode kembali: $?"kode kembali: 0Berkas unit contoh pada topik ini sengaja menunjuk skrip di /usr/local/bin, dan verify langsung menemukan masalahnya karena berkas itu belum ada di lingkungan latihan:
# memeriksa berkas unit yang sudah ditulis
cp arsip-cadangan.service /tmp/kerja-berkas-unit/
systemd-analyze verify /tmp/kerja-berkas-unit/arsip-cadangan.service
echo "kode kembali: $?"arsip-cadangan.service: Command /usr/local/bin/arsip-cadangan.sh is not executable: No such file or directory
kode kembali: 1Pesan Command ... is not executable justru memperlihatkan manfaat verify, yaitu jalur ExecStart diperiksa keberadaannya sebelum unit dipasang. Pada server sungguhan, skrip dipasang lebih dahulu ke lokasi tersebut, sehingga pemeriksaan berakhir senyap. Kesalahan ketik pada nama direktif juga tertangkap, sebagaimana uji berikut pada unit yang kuncinya salah tulis:
# unit dengan nama kunci yang salah ketik
printf '[Unit]\nDescription=Uji salah ketik\n\n[Service]\nType=oneshot\nExceStart=/bin/true\n' > /tmp/kerja-berkas-unit/salah-ketik.service
systemd-analyze verify /tmp/kerja-berkas-unit/salah-ketik.service
echo "kode kembali: $?"/tmp/kerja-berkas-unit/salah-ketik.service:6: Unknown key 'ExceStart' in section [Service], ignoring.
salah-ketik.service: Service has no ExecStart=, ExecStop=, or SuccessAction=. Refusing.
Unit salah-ketik.service has a bad unit file setting.
kode kembali: 1Kunci ExceStart tidak dikenal sehingga diabaikan, dan akibatnya unit itu tidak memiliki ExecStart= sama sekali, lalu berkasnya dinilai rusak secara keseluruhan. Ketiga keluaran di atas menunjukkan pola pelaporannya, yaitu nama berkas, nomor baris bila relevan, dan kalimat penyebabnya.
Memasang berkas unit#
Berkas unit buatan pengelola dipasang di /etc/systemd/system, sedangkan /usr/lib/systemd/system adalah wilayah manajer paket yang isinya dapat tertimpa pembaruan. Langkah pemasangannya berurutan, yaitu menyalin skrip dan berkas unit, memuat ulang daftar unit, lalu mengaktifkan layanannya:
# tidak-dijalankan
# pemasangan menuntut hak root dan systemd yang berjalan, keduanya tidak ada di sandbox
sudo cp arsip-cadangan.sh /usr/local/bin/
sudo cp arsip-cadangan.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now arsip-cadangan.servicedaemon-reload wajib karena systemd tidak memantau berkas baru di disk, sedangkan enable --now sekaligus membuat layanan aktif saat boot dan menjalankannya sekarang. Berkas yang sudah terpasang dapat diperiksa dengan systemctl cat arsip-cadangan.service, yang menampilkan isi berkas efektif beserta lokasinya. Apabila layanan perlu diubah, sunting berkasnya di /etc/systemd/system, berikan daemon-reload, lalu jalankan ulang layanannya. Penyuntingan tidak pernah dilakukan pada berkas di /usr/lib/systemd/system. Setelah dipasang, hasil eksekusinya dapat dipantau lewat systemctl status arsip-cadangan.service, dan arsip yang dihasilkannya menumpuk di /var/backups/arsip sesuai argumen pada ExecStart.
Kesalahan umum#
- Menulis jalur relatif pada
ExecStart=. systemd tidak menjalankan shell dan tidak mencari program lewat PATH untuk perintah utamanya, sehingga jalurnya wajib absolut. - Melupakan
chmod +xpada skrip. verify melaporkanCommand ... is not executable, dan layanan yang tetap dipasang berakhir gagal dengan status 203 karena programnya tidak bisa dieksekusi. - Menaruh unit buatan sendiri di
/usr/lib/systemd/system. Direktori itu milik manajer paket dan isinya dapat tertimpa pembaruan, sedangkan unit kustom ditaruh di/etc/systemd/system. - Menyunting berkas unit lalu heran karena tidak berpengaruh. systemd membaca berkas ke memorinya, sehingga
daemon-reloadwajib diberikan setiap kali berkasnya berubah.
Ringkasan#
- Layanan sekali jalan didefinisikan oleh tiga bagian berkas unit, yaitu metadata
[Unit], cara eksekusi[Service], dan aturan enable[Install]. ExecStartwajib berupa jalur absolut ke program yang siap dieksekusi, sehingga skripnya diuji dulu secara manual sebelum dipasang.systemd-analyze verifymemeriksa sintaks dan jalurExecStarttanpa menuntut systemd yang berjalan, dan hasil senyap dengan kode kembali nol berarti sah.- Unit kustom dipasang di
/etc/systemd/system, diikutidaemon-reloaddanenable --nowagar aktif sejak boot sekaligus berjalan saat itu juga.
Referensi#
- systemd.unit(5) — freedesktop.org — Format umum berkas unit dan makna setiap bagiannya.
- systemd.service(5) — freedesktop.org
— Opsi bagian
[Service], termasukType=oneshotdanExecStart=. - systemd-analyze(1) — freedesktop.org — Subperintah verify beserta pemeriksaan yang dilakukannya.
- systemd.unit(5) — Ubuntu manpages — Manual berkas unit pada Ubuntu 24.04, versi yang dipakai jalur ini.