Backup data dg DVCS

Sejak bbrp hari yang lalu saya nyari2 cara tuk membackup data (er.. foto sih tepatnya =D) dg mudah di harddisk eksternal. Berhubung saya jg pengen ada fasilitas versioning, cara backup dg rsync tidak bisa diambil mentah2.

Aplikasi selanjutnya yg terpikir adalah Time Machine yg ada di Mac OS X. Namun setelah baca2, Time Machine tidak bisa melakukan backup secara selektif dalam artian hanya direktori yg dipilih saya yang dibackup, akhirnya Time Machine juga tidak jadi dipilih. Time Machine hanya bisa diatur untuk mengecualikan direktori yg dipilih dan bukan sebaliknya. Kalau begini kondisinya, sudah tentu harddisk eksternal saya akan cepat penuh berhubung Time Machine akan melakukan backup sistem secara keseluruhan.

Sempat mikir juga tuk menggunakan DVCS seperti Git. Namun sejak ingat Git dan DVCS lain akan menduplikasi data yg ada di harddisk internal ke dalam repositori lokalnya juga, pemborosan harddisk akan tetap terjadi. Walau Git melakukan kompresi data, tapi untuk data binari seperti foto rasanya tidak akan begitu berpengaruh. Jadi kalau kita punya foto sebanyak 10GB, maka Git akan menyalinnya ke repositori lokal sehingga total data yg kita simpan bisa mencapai 20GB. Saya jadi ragu tuk menggunakan DVCS tuk membackup data foto.

Loh kok jadi kontradiksi dengan judul?

Tidak, karena tulisan ini belum selesai =P Kekhawatiran tadi akhirnya bisa diakalin sehingga tidak akan terjadi duplikasi data pada harddisk yg sama. Harddisk internet dan eksternal masing-masing akan menyimpan 1 salinan data saja, jadi sangat efisien. Bagaimana caranya?

Caranya adalah dengan meletakkan repositori lokal yang seharusnya ada pada harddisk internal ke harddisk eksternal!

Agar repositori lokal tersebut tetap bisa diakses dari harddisk internal, sebuah symlink digunakan untuk menunjuk direktori repositori lokal yg ada di harddisk eksternal tersebut. Teknik menggunakan symlink ini belum tentu bisa digunakan di seluruh DVCS. Saya sudah mencoba dengan Git dan Bzr dan ternyata keduanya bisa melakukan seluruh skenario yg saya inginkan butuhkan, yang akan saya tunjukkan berikut ini.

Katakanlah direktori yg ingin dibackup adalah ~/Foto/ dan harddisk eksternal ada di /eksternal/

  1. Menginisialisasi repositori

    $ cd Foto
    $ git init
    $ mv .git /eksternal/Foto.git
    $ ln -s /eksternal/Foto.git .git
    
  2. Backup data yang ada

    $ git add .
    $ git commit -a -m "backup"
    

    Proses ini bisa saja dilakukan secara terjadwal. Jangan lupa mengecek dulu apakah harddisk external tsb sedang dipasang atau tidak.

  3. Mengembalikan data dari direktori backup.

     $ mkdir FotoBaru
     $ cd FotoBaru
     $ ln -s /eksternal/Foto.git .git
     $ git checkout HEAD -- .
    

    Selain pake cara di atas, bisa jg lgs git clone direktori /eksternal/Foto.git namun direktori baru yg terbentuk akan membengkak 2x lipat karena berisi repositori lokal dan juga salinan lokal.

    Jika menggunakan Bzr, perintah terakhir diganti menjadi bzr revert

  4. Mengembalikan file tertentu dari sebuah revisi tertentu.

     $ git checkout [revisi] -- [nama/file]
    

    jika menggunakan Bzr, maka perintah di atas menjadi seperti berikut.

     $ bzr revert -r[revisi] [nama/file]
    

Kira-kira seperti itu saja =D ada yang mau mencoba dg DVCS lainnya?

Oh ya.. direktori backup yang ada di harddisk eksternal tidak bisa dibuka begitu saja dengan untuk melihat data-data didalamnya karena data tersimpan dalam format repositori DVCS yang digunakan. Untuk melihatnya tentu saja harus dikembalikan dulu ke salinan lokal dg aplikasi DVCS yang digunakan. Cara ini memang sepertinya hanya ditujukan bagi yang ingin menjadikan harddisk eksternal tsb hanya sebagai tempat backup, bukan tempat berbagi data jg dg orang lain. Asumsinya kalau untuk berbagi data, maka isi harddisk dapat dilihat scr langsung tanpa bantuan aplikasi backup yg dipakai.

Yang asik dari …

Beberapa hal dari VCS alias Version Control System yang saya rasa lebih asik daripada VCS yang lain (tentu saja yg pernah saya pakai). Hal-hal menarik yg saya tuliskan di sini adalah hal-hal yang sudah saya pakai. Tentu saja masih banyak hal menarik yg belum saya temukan/rasakan. Silakan ditambahkan kalau mau..

Git

  1. Github
  2. Bikin cabang di tempat yang sama! Jadi ngga perlu ganti2 direktori kalau mau bikin/gabung cabang (ref: git branch).
  3. Tidak perlu pusing mikirin perubahan nama berkas. Perubahan nama berkas secara otomatis tercatat.
  4. Bisa nyomot perubahan dalam sebuah commit pada sebuah cabang untuk diterapkan pada cabang yang lain (ref: git cherry-pick).

Daftar akan terus bertambah xD

Bazaar

  1. Launchpad

Duh.. gak kok gak bisa nemuin yang lain =))

Yang pasti, pada dasarnya Distributed VCS >> Centralized VCS.

Subversion

  1. Google Code Hosting
  2. Repositori “parsial”. Direktori apa saja bisa jadi root directory dari sebuah repositori Subversion.

Itu aja kayanya. Saya bukan penggemar VCS yang terpusat lagi =D

Perintah dasar Bazaar

Kira-kira inilah perintah-perintah dasar kalau ingin menggunakan Bazaar.

  1. Membuat sebuah cabang baru.

    $ bzr init
    

    Perintah tersebut dijalankan di bawah sebuah direktori yang akan menjadi cabang.

  2. Menambahkan berkas/direktori ke dalam cabang.

    $ bzr add satu dua tiga ...
    

    Andai tidak ada berkas/direktori yang disebut, maka seluruh berkas atau direktori yang ada akan dimasukkan.

  3. Menyimpan perubahan.

    $ bzr commit
    

    Sebuah editor akan terbuka. Tulis catatan revisi di sana. Simpan lalu keluar dari editor agar perubahan tersimpan ke dalam cabang Bazaar.

  4. Menghapus berkas/direktori.

    Hapus saja berkas/direktori yang ingin dihapus, lalu jalankan bzr commit.

Sebenarnya sudah itu saja perintah-perintah dasarnya. Namun rasanya kurang lengkap kalo tidak dilanjutkan dengan beberapa perintah dasar-namun-sedikit-lanjutan yang juga berkaitan dengan pengerjaan secara bersama-sama.

  1. Membuat cabang baru dari sebuah cabang Bazaar

     $ bzr branch utama baru
    

    Cabang Bazaar bernama utama akan disalin menjadi sebuah cabang baru bernama baru.

  2. Menarik perubahan dari cabang induk.

    $ bzr pull http://repo/bzr/utama/
    

    Ada kalanya perubahan gagal ditarik karena cabang induk tersebut telah mengalami perubahan. Jika hal ini yang terjadi, maka operasi yang harus dilakukan adalah penggabungan cabang.

    $ bzr pull http://sebuah/cabang/
    bzr: ERROR: These branches have diverged. Use the merge command to reconcile them.
    
  3. Menggabungkan cabang yang ada dengan cabang yang lain.

    $ bzr merge http://repo/bzr/lain/
    

    Jika beruntung, operasi dapat berjalan lancar tanpa ada gangguan apa-apa.

    $ bzr merge http://sebuah/cabang/
    ...
    All changes applied successfully.
    

    Penggabungan cabang dengan bzr merge ini tidak langsung disimpan menjadi revisi baru. Oleh karena itu perlu dilakukan penyimpanan dengan bzr commit.

    Konflik bisa saja terjadi pada saat menggabungkan cabang. Hal ini disebabkan karena ada berkas sama yang mengalami perubahan secara terpisah pada kedua buah cabang.

    $ bzr merge http://sebuah/cabang/
    ...
    Text conflict in sebuahberkas
    1 conflicts encountered.
    

    Berkas yang konflik biasanya akan ditandai dengan akhiran .BASE, .OTHER, .THIS. Berkas yang diakhiri .BASE adalah versi dasar bersama dari kedua cabang yang mengalami konflik. Berkas dari versi cabang yang ada ditandai dengan akhiran .THIS sedangkan berkas dengan akhiran .OTHER adalah versi dari cabang lain yang digabungkan.

    induk +--> satu ----+--> satu -->
          |            /
          +--> dua  --'
    

    Sebagai ilustrasi, andai ada cabang bernama induk yang disalin menjadi dua cabang baru, yaitu satu dan dua. Ada sebuah berkas bernama index.html pada cabang induk yang kemudian dimodifikasi secara terpisah pada cabang satu dan dua. Ketika cabang satu ingin melakukan penggabungan cabang dengan cabang dua, maka berkas index.html tadi akan mengalami konflik karena berkas tersebut telah mengalami modifikasi.

    Berkas index.html asli yang berasal dari cabang induk akan diberi nama index.html.BASE. Berkas yang berasal dari cabang dua akan diberi nama index.html.OTHER sedangkan index.html.THIS berasal dari cabang satu, yaitu cabang yang sedang dikerjakan.

    Cabang yang ingin digabungkan haruslah berasal dari satu cabang induk yang sama. Jika tidak, maka penggabungan tidak dapat dilakukan karena tidak dapat ditelusuri perubahan yang terjadi.

    $ bzr merge http://cabang/tetangga/
    bzr: ERROR: Branches have no common ancestor, and no merge base revision was specified.
    
  4. Mengatasi konflik.

    $ bzr resolve berkas-konflik
    

    Sebagai contoh ada berkas konflik bernama index.html. Perbaikilah berkas tersebut lalu jalankan

    $ bzr resolve index.html
    

    Berkas lain .BASE, .THIS, dan .OTHER akan dihapus setelah konflik diatasi.

  5. Menyimpan perubahan ke cabang lain.

    $ bzr push bzr+ssh://repo/bzr/utama/
    

    Cabang yang ingin disimpan haruslah merupakan kelanjutan dari cabang tujuan. Jika tidak, maka proses penyimpanan akan gagal.

    $ bzr push bzr+ssh://repo/bzr/utama/
    bzr: ERROR: These branches have diverged.  Try using "merge" and then "push".
    

    Oleh karena itu, cabang yang ada harus disinkronsasi dengan cabang tujuan tersebut dengan menjalankan bzr merge yang kemudian diikuti dengan bzr push untuk mengulangi penyimpanan.

    Seperti halnya menggabungkan cabang, menyimpan cabang yang ingin disimpan ke cabang lain haruslah berasal dari satu cabang induk yang sama.

  6. Membatalkan perubahan.

    $ bzr revert sebuah-berkas
    

    Andai kita memodifikasi berkas bernama index.html namun sampai suatu ketika kita ingin membatalkan perbuahan tersebut dan mengembalikkannya ke versi terakhir yang tersimpan dalam cabang bzr. Maka kita cukup menjalankan perintah berikut

    $ bzr revert index.html
    

    Sebuah berkas bernama index.html.~1~ akan terbentuk dan berisi perubahan yang sempat kita lakukan. Selain itu, berkas index.html akan berubah isinya sesuai dengan versi terakhir yang ada.

    Jika berkas index.html kita hapus lalu kita menjalankan bzr revert index.html, maka berkas index.html akan muncul kembali dengan isi dari versi terakhir. Berkas index.html.~1~ tidak akan terbentuk karena tidak ada berkas perubahan.

    Jadi, andai suatu ketika merasa perubahan yang dilakukan sangat kacau dan ingin diulang semua, hapus saja semua berkas yang ada lalu panggil bzr revert.

    $ rm -rf *
    $ bzr revert
    

Sepertinya itu dulu. Kalau sudah paham perintah-perintah di atas, saya rasa sudah bisa lah menggunakan Bazaar untuk keperluan sehari-hari termasuk menjadi pengembang BlankOn =D

Oh iya. Cabang Bazaar ini memang bisa dianggap sebagai satu direktori beserta isinya. Sehingga kalau ingin menyalin maupun mengamankan sebuah cabang Bazaar, cukup simpan direktori tersebut. Lebih tepatnya, direktori .bzr yang ada di dalamnya. Direktori .bzr tersebut berisi seluruh catatan revisi yang dilakukan dari awal cabang dibuat.

Tunnel koneksi

Sebagai pengembang BlankOn, maka salah satu server yang sering saya dikunjungi adalah yeyen alias irgsh alias dev.boi. Namun, mengakses server itu dari sini perlu ditemani oleh sebungkus indomie yang belum dimasak sehingga bisa masak sambil nungguin koneksi beres xD Ini apa koneksi Internet di Belanda kurang cepet tuk ngakses mesin tsb? Di Finlandia kabarnya juga seperti itu =P

Untungnya saya punya akses yang lumayan cepat ke sebuah mesin yang punya koneksi lumayan cepat ke mesin yeyen.. Dengan kata lain, ada mesin perantara yang punya koneksi lumayan ke saya dan yeyen. Hal ini berarti saya bisa menggunakan mesin tersebut untuk dijadikan tukang ojek seluruh data yang mau saya kirim/terima ke/dari mesin yeyen =D

Kalau mau mengakses layanan http dengan browser, saya biasanya membuka tunnel via ssh dengan menggunakan socks proxy. Sintaksnya kira2 seperti ini.

$ ssh -D12345 mesin.perantara

Port 12345 adalah port dari socks proxy yang akan digunakan. Browser tinggal diatur agar menggunakan socks proxy pada port tersebut supaya koneksi dilewatkan melalui mesin perantara.

Namun.. berhubung koneksi dari tempat saya itu sudah cukup cepat tuk mengakses situs2 lainnya, mengapa seluruh koneksi harus dilewatkan ke mesin perantara terlebih dahulu? Maka dari itu, akan lebih baik apabila kita bisa memilah-milih koneksi mana yang mau dilewatkan atau langsung.

Konfigurasi proxy di browser Firefox yang saya gunakan hanya bisa membuat pengecualian situs mana yang tidak dilewatkan melalui perantara. Yang saya inginkan adalah kondisi sebaliknya dimana saya ingin menentukan situs yang ingin dilewatkan melalui perantara. Untungnya, Firefox mendukung fasilitas konfigurasi proxy otomatis sehingga saya bisa mengatur lewat konfigurasi yang ini.

Caranya adalah dengan membuat berkas skrip konfigurasi proxy otomatis seperti yang berikut ini.

function FindProxyForURL(url, host) {
   if (shExpMatch(url, "*dev.blankonlinux.or.id/*") ||
       shExpMatch(url, "*irgsh.blankonlinux.or.id/*") ||
       shExpMatch(url, "*yeyen.blankonlinux.or.id/*") ||
       shExpMatch(url, "*cecunguk.blankonlinux.or.id/*") ||
       shExpMatch(url, "*.ubuntu-id.org/*")) {

      return "SOCKS 127.0.0.1:12345; DIRECT";
   }

   return "DIRECT";
}

Seperti yang tertulis di atas, koneksi ke beberapa situs akan dialihkan melalui SOCKS proxy di 127.0.0.1 port 12345. Jika proxy tersebut tidak tersedia (misalnya saya belum membuka koneksi tunnel tsb), maka koneksi langsung tanpa proxy (DIRECT) akan dibuat. Untuk koneksi menuju situs selain yang disebutkan di sana, koneksi langsung akan digunakan.

Simpan skrip di atas ke dalam sebuah berkas, misalnya proxy.pac. Lalu tunjuk berkas tersebut dari kolom pengaturan konfigurasi otomatis, misalnya file:///Users/iang/Sites/proxy.pac. URL tersebut akan menunjuk ke berkas yang ada di /Users/iang/Sites/proxy.pac. Silakan disesuaikan sendiri.

Urusan dengan koneksi http/https bisa dianggap sudah selesai. Namun, saya juga masih harus dapat mengakses mesin yeyen melalui koneksi ssh, misalnya untuk mengirim perubahan pada cabang Bazaar yang ada di mesin yeyen. Bagaimana supaya koneksi bisa dilewatkan melalui mesin perantara juga? tentu saja melalui tunneling =D

Caranya kira2 seperti ini.

$ ssh -L2222:yeyen.blankonlinux.or.id:22 mesin.perantara

Dengan menjalankan perintah tersebut, maka di mesin kita sendiri (lokal = L) akan dibuka port 2222 dimana koneksi menuju port tersebut akan diteruskan ke mesin yeyen.blankonlinux.or.id port 22 melalui si mesin.perantara.

Dengan ini, saya bisa menggunakan port tersebut saat mengirim perubahan pada cabang Bazaar. Misalnya seperti berikut.

$ bzr push bzr+ssh:[email protected]:2222/bzr/meuligoe/firefox/

Yayyaa.. begitulah kira2.. silakan dicoba2 sendiri =P

Bazaar di Nexenta

Bazaar (bzr) di Nexenta 1.0 udah terlalu jadul. Jadi enakan ngompile ndiri aja =D

  • Paket tambahan kalo mo ngompile..

    $ sudo apt-get install python-dev
  • Donlod bzr yg baru lalu di-extract

    $ wget --no-check-certificate 
      https://launchpad.net/bzr/1.9/1.9/+download/bzr-1.9.tar.gz
    $ tar xzf bzr-1.9.tar.gz
    $ cd bzr-1.9
  • Compile dan instal ke $HOME/sunos

    $ python setup.py install --prefix=$HOME/sunos

    sesuaikan target instalasi sesuai kebutuhan.

Instalasi kelar, sekarang atur2 path.

$ export PATH=$PATH:$HOME/sunos/bin
$ export PYTHONPATH=$PYTHONPATH:$HOME/sunos/lib/python2.4/site-packages