Komentar terhadap skrip bekudancair.

Di milis Ubuntu, baru-baru ini saya membuat pendapat bahwa skrip bekudancair itu berbahaya seperti halnya automatix. Saya akan menuliskan alasan-alasan yang melatarbelakangi pendapat saya itu di sini.

Skrip yang saya komentari adalah skrip yang saya unduh dari tautan yang disebut pada blog yang membahas bekudancair. Silakan buka http://rapidshare.com/files/47935147/beku.tar.gz untuk mengunduhnya.

Masalah utama yang ada pada skrip tersebut adalah asumsi berlebihan mengenai kondisi sistem dan cara menjalankan skrip tsb.

Selain menuliskan masalah yang ada, saya juga akan mencoba memberikan solusinya.

Masalah 1: Skrip berasumsi sistem tidak pernah diutak atik.

Skrip menempelkan diri pada /etc/rc.local yang normalnya akan dijalankan pada saat sistem baru dinyalakan. Berkas tersebut ditambahi isinya dengan beris perintah seperti berikut.

sudo rsync -av --delete /home/.beku/$namadir/ /home/$namadir/

Nilai $namadir akan saya jelaskan nanti.

Skrip mencoba melakukan mekanisme pencegahan memasukan baris tersebut lebih dari satu kali dengan melakukan pengecekan isi /etc/rc.local dengan menggunakan grep terhadap sudo rsync -av --delete /home/.

Berhubung isi default dari skrip tersebut diakhiri dengan exit 0, maka setiap perintah yang ditambahakan (dg bantuan skrip ini) harus dituliskan sebelum exit 0 tersebut. Untuk itu, skrip akan menghapus seluruh baris yang mengandung exit 0 dengan bantuan grep, menuliskan perintah2 baru, dan memasukkan kembali exit 0.

Untuk menggambarkan masalah yang ada, saya akan menggunakan contoh.

Apa yang terjadi jika Anda pernah mengubah berkas /etc/rc.local? Apa yang terjadi jika Anda menggunakan exit 0 sebagai bagian perubahan yang Anda lakukan? Bagaimana jika Anda juga menambahkan perintah sudo rsync -av --delete /home/ di sana?

Skrip bekudancair akan mengabaikan itu semua. Perubahan yang Anda lakukan akan menjadi berantakan dan pada akhirnya skrip /etc/rc.local itu sendiri juga menjadi berantakan. Intinya, sistem bisa jadi berantakan juga.

Solusi sederana: siapkan 1 buah skrip yang hanya berisi perintah2 yang dibuat oleh bekudancair sehingga bekudancair hanya akan mengbah 1 skrip ini saja. Skrip ini kemudian bisa saja dijalankan dari /etc/rc.local namun penanganan exit 0 harus dilakukan dengan benar tidak asal grep. Lebih baik lagi jika dipanggil dari sebuah skrip lain di /etc/rc.d/.

Masalah 2: Home directory diasumsikan ada di bawah /home/

Nilai dari variabel $namadir yang saya sebut sebelumnya dibuat dengan cara menghapus 6 huruf pertama dari nilai home directory user yang tertulis pada variabel $HOME. Cara ini akan menghasilkan nilai yang benar jika memang home directory ada di bawah /home/ (atau direktori lain yang hanya mengandung 4 huruf) dan akan salah jika tidak.

Solusi: gunakan basename untuk mengambil bagian terakhir dari sebuah path.

$ namadir=$(basename $HOME)

Jika ada slash di belakangnya, basename juga akan menanganinya dengan benar.

$ basename /home/iang/
iang

Gagal menangani adanya slash di akhir $namadir juga akan membawa masalah yang akan saya tuliskan sebagai masalah 3.

Masalah 3: Nilai $namadir tidak dicek lagi

Untuk membuat cetakan direktori, bekudancair menggunakan rsync. Berikut ini adalah perintah yang digunakan.

$ sudo rsync -av --delete /home/$namadir /home/.beku/

Ada satu perbedaan kecil di sana yang dapat mengakibatkan hasil yang sangat berbeda. Jika $namadir tidak diakhiri oleh slash /, maka berkas atau direktori tsb akan disalin ke /home/.beku/. Jika sebelumnya ada /home/iang maka akan ada /home/.beku/iang. Jika /home/iang di sana adalah sebuah direktori, maka direktori tersebut akan disalin ke bawah /home/.beku/.

Namun jika $namadir diakhiri oleh slash, maka isi direktori tersebut akan disalin ke bawah /home/.beku/. Sehingga isi /home/.beku/ bukan lagi direktori yang disebut dalam $namadir, melainkan isi dari direktori tersebut.

Solusi pertama: pastikan $namadir tidak diakhiri oleh slash.

Solusi kedua yang lebih pasti: buat direktori /home/.beku/$namadir/, lalu salin isi /home/$namadir/ ke /home/.beku/$namadir/

$ mkdir /home/.beku/$namadir/
$ rsync -av --delete /home/$namadir/ /home/.beku/$namadir/

Masalah 4: Skrip diasumsikan dijalankan oleh sebuah user biasa dengan bantuan sudo

Direktori yang ingin diamankan oleh skrip adalah /home/$namadir dimana nilai $namadir diambil dari nilai $HOME.

Nilai $HOME akan berisi direktori user jika user tersebut yang menjalankan skrip. Jika tidak? berantakan lah jadinya.

Solusi? Saya tidak tahu apa solusinya karena sangat tergantung bagaimana maunya si pembuat skrip.

Masalah lain

Beberapa masalah lain:

  1. Pengecekan apakah skrip sudah mengubah isi /etc/rc.local tidak dilakukan dengan benar. Skrip hanya mengecek jika ada SATU buah baris yang berisi tulisan sudo rsync -av --delete /home/. Jika ada 0 maupun lebih dari satu, maka skrip akan menganggap /etc/rc.local belum diubah.

    Solusinya adalah bagian dari solusi pada Masalah 1.

  2. Skrip berasumsi tidak ada berkas bernama temp di bawah direktori kerja tempat dimana skrip dijalankan dan menggunakannya untuk menulis isi sementara dari berkas /etc/rc.local.

    Solusinya: gunakan nama berkas yang bisa diasumsikan lebih unik dan belum pernah dipake. Misalnya letakkan di bawah /tmp, gunakan bekudancair menjadi bagian dari namanya, tambahkan timestamp yang diambil dari date +%s, tambahkan angka acak, tambahkan pid dari proses skrip tsb, dsb.

Saran lain

Masalah utama yang saya temukan dalam skrip bekudancair rasanya sudah saya bahas semua. Saya juga ingin memberikan beberapa saran untuk skrip ini.

  1. Direktori backup diletakkan di tempat lain, misalnya di sebuah direktori di bawah /var/.

  2. Lepaskan kebutuhan untuk dijalankan oleh user yang home directory-nya akan diamankan (Masalah 4). Skrip seharusnya bisa mengambil informasi home directory user dari tempat lain. Efek samping positifnya adalah nama user yang home directory-nya ingin diamankan atau dikembalikan dapat disebut sebagai parameter.

    Contoh cara mendapatkan home directory seorang user adalah seperti berikut.

    namauser=$1
    homedir=$(eval echo ~$namauser)
    

Penutup

Skrip bekudancair ini mungkin sudah bisa bekerja sesuai fungsinya jika seluruh asumsi yang dipakai terpenuhi. Sudah cukup untuk dipakai untuk keperluan pribadi. Namun jika asumsi-asumsi tadi tidak semuanya terpenuhi, maka siap-siap saja akan ada kekacauan yang terjadi.

4 thoughts on “Komentar terhadap skrip bekudancair.”

  1. 0.
    Saat sistem dijalankan via rc.local $HOME mungkin belum didefinisikan atau paling pol ke /root. Untuk dapatkan rumah sebuah pengguna harus ambil dari gecos yang ada di /etc/passwd.

    1.
    Gunakan mktemp untuk membuat direktori/berkas sementara

    2.
    Gunakan upstart (Ubuntu/Fedora) atau SysVInit di /etc/rc.d untuk menjalankan skrip di awal boot.

    Jadi apakah ada patch dan bisa masuk repo BlankOn? hehehe

  2. Wah ada mktemp toh.. Makasih makasih..

    ngambil home dir cara yang benar itu seperti apa ya? kan belum tentu home dir tertulis di /etc/passwd misalnya karena pake LDAP.

  3. inilah hebatnya opensource, selalu ada orang yang berbaik hati menganalisa program/script, omong2, script bekudancair yang saya buat ini emang sangat quick and dirty mas, dan disitu berkali2 saya tekankan bahwa script tersebut masih sangat experimental, tapi anehnya sampai sekarang belum ada yang komplain serius 😀 , oh iya, kenapa scriptnya gak di oprek aja mas, kemudian di release versi yg lebih matang :), saya bikinnya tahun 2007 dan pasti sudah sangat outdated >_<,
    makasih,
    Mukhlis Amien

Leave a Reply