Untuk beberapa proyek saya membuat sebuah service/daemon menggunakan Python agar bisa mengontrol sistem secara keseluruhan dari jarak jauh, service ini juga akan berjalan otomatis ketika Raspberry Pi dinyalakan. Di Linux, lain distribusi lain juga caranya memulai dan menghentikan service (sekarang ini beberapa menggunakan Upstart, dan ada juga systemd). Saya sendiri menggunakan versi Jessie dari distribusi Raspbian di Raspberry Pi 2 saya, dan dalam kasus ini cara yang benar untuk melakukannya adalah dengan menggunakan sebuah "init script".
Letak dari init script adalah di folder
/etc/init.d
. Disana kamu bisa menemukan berbagai script yang misalnya, untuk menjalakan sistem jaringan atau server printer. Raspbian Jessie menggunakan sistem init yang termasuk lama, yaitu Sys V yang artinya bahwa script-script tersebut dijalankan berdasarkan tautan simbolis (symbolic links) yang berada dalam folder
/etc/rc.x
.
Dokumentasi dari Debian menjelaskan secara detil mengenai hal ini.
Dan langsung saja, init script yang akan dijabarkan berikut ini akan membuat script Python (atau script lainnya seperti Perl) bisa berjalan di latar belakang ketika Raspberry Pi dinyalakan. Perlu diingat, service berarti sebuah program yang berjalan di latar belakang tanpa memerlukan interaksi dengan pengguna. Maka dari itu service wajib berjalan dalam mode "daemon" yang mana sangat sulit dan rumit untuk diimplementasikan langsung pada bahasa pemrograman termasuk Python tanpa bantuan dari sisi sistem operasi, karena proses ini akan melibatkan teknik yang namanya
forking proses sebanyak dua kali dan
trik trik kotor lainnya.
Maka dari itu, kita bisa menggunakan fitur yang sudah ada yang juga sangat mudah untuk digunakan yaitu perintah start-stop-daemon
yang telah menyediakan segala kebutuhan kita untuk bisa menjalankan script yang kita buat di latar belakang secara otomatis.
Pada contoh ini nama service saya adalah govindaservice, silahkan disesuaikan.
Buat file service dengan nama govindaservice.sh
dan buat menjadi executable, chmod a+x govindaservice.sh
#!/bin/sh
DIR=
/home/pi/govinda
DAEMON=$DIR
/main
.py
DAEMON_NAME=govindaservice
PATH=
/usr/local/sbin
:
/usr/local/bin
:
/usr/sbin
:
/usr/bin
:
/sbin
:
/bin
:
/opt/bin
:
/home/pi
:
/home/pi/bin
:home
/pi/govinda
:
/var/data/pi/govinda
:
/var/data/pi/bin
DAEMON_OPTS=
""
DAEMON_USER=root
PIDFILE=
/var/run/
$DAEMON_NAME.pid
.
/lib/lsb/init-functions
do_start () {
log_daemon_msg
"Memulai service $DAEMON_NAME daemon"
start-stop-daemon --start --background --pidfile $PIDFILE --
make
-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
log_end_msg $?
}
do_stop () {
log_daemon_msg
"Menghentikan service $DAEMON_NAME daemon"
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}
case
"$1"
in
start|stop)
do_${1}
;;
restart|reload|force-reload)
do_stop
do_start
;;
status)
status_of_proc
"$DAEMON_NAME"
"$DAEMON"
&&
exit
0 ||
exit
$?
;;
*)
echo
"Cara pakai: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
exit
1
;;
esac
exit
0
start-stop-daemon
perlu mengetahui dan mengenali proses yang berkaitan dengan service, tujuannya agar (1) dia bisa tahu kalau prosesnya sudah berjalan atau sedang berjalan sehingga dia tidak perlu menjalankannya lagi, dan (2) dia bisa menemukan proses yang telah berjalan tersebut dan mengakirinya ketika diminta. Dalam kasus ini yang menggunakan script Python maka nama prosesnya adalah "python" jadi menggunakan nama proses untuk mengenali proses mana yang dimaksud tidaklah mungkin karena proses lain yang juga dibuat menggunakan Python akan memiliki nama proses yang sama juga, dan ini akan jadi membingungkan dan berbahaya bila salah kill.
Solusinya kita membuat start-stop-daemon
agar menyimpan PID (Id proses) menggunakan argumen --pidfile #PIDFILE --make-pidfile
. Ketika diminta untuk menjalankan proses ia akan mencari file $PIDFILE yang pada script diatas akan menjadi /var/run/govindaservice.pid
(pada Raspberry Pi aslinya terletak di /run/govindaservice.pid
) karena adanya fitur tautan simbolis.
Selain itu, kita menggunakan flag --background
dari start-stop-daemon
untuk menjalankan script kita di background, "--chuid
" untuk mengatur user yang menjalankan script (dengan "--user
" untuk mencari script yang dijalankan oleh user tersebut ketika kita mencoba untuk menentukan jika ia sudah atau sedang berjalan) dan "--start
" untuk menentukan apa yang ingin kita jalankan. Opsi dari start-stop-daemon
diakhiri dengan double-hyphen dan kemudian kita menambahkan pada $DAEMON_OPTS jika terdapat parameter atau argumen yang harus dilewatkan ke daemon sendiri.
Ketika menghentikan daemon --retry10
berarti bahwa pertama dari semua tahap sinyal TERM dikirim ke proses, dan 10 detik kemudian ia akan memeriksa jika proses yang diminta untuk mati itu masih berjalan atau tidak dan jika masih ia akan mengirim KILL atau sinyal mati paksa (yang tentunya akan berhasil).
Menggunakan Init Script
Untuk bisa menggunakan script ini secara nyata, tempatkan script Python mu di tempat yang kamu suka dan pastikan ia bisa dieksekusi (dengan chmod 755 main.py
atau chmod a+x main.py
) dan juga jangan lupa mulai baris script dari main.py
dengan menggunakan Python interpreter (misal #!/usr/bin/env python
). Sunting init script sesuai keperluan mu.
Langkah selanjutnya adalah menyalin script service yang telah dibuat diatas ke /etc/init.d
dengan sudo cp govindaservice.sh /etc/init.d
. Sekali lagi pastikan govindaservice.sh
juga sudah executable dan menggunakan UNIX line-endings. Terakhir untuk mengupdate database system-ctl jalankan perintah sudo sysctl reload
. Pada titik ini kamu seharusnya sudah bisa menjalankan script Python mu menggunakan perintah sudo service govindaservice start
, memeriksa statusnya dengan sudo service govindaservice status
dan untuk menghentikan menggunakan sudo service govindaservice stop
.
Terakhir untuk membuat Raspberry Pi menggunakan init script mu pada waktu dan urutan yang tepat, satu langkah terakhir ini sangat diperlukan: menjalankan perintah sudo update-rc.d govindaservice.sh defaults
. Perintah ini akan menambahkan tautan simbolis dari service mu ke folder /etc/rc.x
sehingga init scriptnya dijalankan pada waktu default saat start up atau ketika Raspberry Pi dinyalakan. Kamu bisa melihat tautan tersebut jika kamu menjalankan perintah ls -l /etc/rc?.d/*govindaservice.sh
. Terkahir jangan lupa reload lagi dengan sudo sysctl reload
. Restart dan coba lihat script mu berjalan otomatis!