Living life and Make it Better

life, learn, contribute

Endy Muhardin

Software Developer berdomisili di Jabodetabek, berkutat di lingkungan open source, terutama Java dan Linux.

Integrasi aplikasi kantor pusat dan cabang [Bagian 1]

Integrasi Aplikasi Pusat Cabang - Bagian I

Beberapa waktu yang lalu, kami di ArtiVisi dihadapkan pada suatu tantangan, yaitu sinkronisasi aplikasi antara pusat dan cabang. Aplikasi pusat maupun cabang memiliki database masing-masing, dan tentunya data transaksi masing-masing pula.

Pada artikel ini, saya akan mengelaborasi proses problem solving yang dilakukan, solusi yang dipilih, dan tentunya dilengkapi dengan source code.

Use Case

Ada beberapa use case yang ingin didukung oleh aplikasi, sebagai berikut :

  • Pusat menambahkan jenis produk baru, data ini harus segera diimplementasikan juga di cabang

  • Transaksi yang dilakukan di cabang harus dikirim ke pusat agar bisa dibuatkan laporan keseluruhan

  • Data pelanggan di cabang harus juga dikirim ke pusat

  • Perpindahan stok barang dari pusat ke cabang dan sebaliknya

Constraint

Bicara requirement, tentu tidak bisa dilepaskan dari constraint. Berikut constraint yang ada :

  • Pusat dan cabang sama-sama terhubung ke internet menggunakan Speedy

  • Karena pakai Speedy, kita bisa mengekspose satu mesin ke internet menggunakan IP Public

  • IP Public tidak dedicated, dan mungkin berubah sewaktu-waktu

  • Server aplikasi dan database di pusat/cabang belum tentu hidup. Kalaupun hidup, belum tentu hidup berbarengan. Bisa saja pusat sedang nyala, cabang mati lampu, dan sebaliknya.

Alternatif Solusi

Setelah kita memiliki requirement dan constraint, tahap berikutnya adalah membuat daftar alternatif solusi. Berikut adalah alternatif yang bisa kita lakukan untuk memecahkan masalah di atas.

  • Remoting

    • Web Services

    • RMI

    • HttpInvoker

  • Messaging

    • JMS

    • Email (POP3/IMAP dan SMTP)

  • File

    • Shared Folder

    • FTP

    • SSH/SCP

  • Database

    • Shared Database

    • Replikasi Database

Pemilihan Solusi

Jaringan publik melalui internet sangat tidak reliable dan memiliki banyak keterbatasan. Kita tidak bisa membuka sembarang port, karena mungkin saja diblokir di tengah jalan. Kita juga tidak bisa menggunakan protokol yang terlalu kompleks atau cerewet (membutuhkan transfer data yang sering). Oleh karena itu, kita bisa menyingkirkan alternatif berikut.

  • Remoting dengan RMI : port tidak standar

  • Messaging dengan JMS : port tidak standar

  • Replikasi MySQL : protokol terlalu kompleks dan cerewet, port tidak standar

Kita harus mempertimbangkan konsumsi bandwidth. Protokol yang rakus bandwidth bisa kita singkirkan, yaitu Remoting dengan WS.

Melihat constraint terakhir, kita juga harus mengeliminasi beberapa alternatif yang mengharuskan pusat dan cabang online bersamaan, yaitu Remoting dengan Spring HTTPInvoker dan File Transfer, baik FTP maupun SSH/SCP.

Dengan demikian, yang tersisa adalah Messaging dengan Email. Kita bisa mengirim data dengan attachment. Untuk menghemat bandwidth, attachment bisa dikompresi. Pusat dan cabang bisa online kapanpun mereka mau, dan akan tetap menerima message. Kalau ada message yang hilang di tengah jalan, orang pusat/cabang bisa menelepon untuk minta dikirim ulang datanya.

Sebagai bonus, dengan memilih email sebagai media transfer data, kita tidak perlu repot-repot mengelola infrastruktur sendiri. Kita bisa gunakan layanan GMail yang gratis, berkapasitas besar, dan memiliki implementasi POP3, IMAP, dan SMTP. Ada satu fitur istimewa dari IMAP, yaitu IMAP-Idle. Fitur ini akan sangat berguna kelak di kemudian hari. Kebetulan GMail sudah mendukung fitur ini.

Desain Implementasi

Baiklah, mari kita implementasikan sinkronisasi melalui email. Ada beberapa pertanyaan lanjutan. Pertama, apa yang ingin dikirim? Sebagai contoh sederhana, kita ingin mengirim data produk baru dari pusat ke cabang. Inilah class Produk.

public class Produk {
  private Integer id;
  private String kode;
  private String nama;
  
  // getter dan setter
}

Bila kita membuat object Produk, datanya akan tersimpan di memori. Kita harus mengkonversi format data di memori ini ke bentuk file, supaya bisa dikirim dalam bentuk attachment. Ada beberapa pilihan lagi di sini, yaitu :

  • java.io.Serializable, konversi dengan ObjectInputStream dan ObjectOutputStream

  • JSON

  • XML

Serializable lebih unggul dalam hal kemudahan coding dan kecepatan marshall/unmarshall. Di Java menulis object ke file sangat mudah dan cepat. Prosesnya sama untuk apapun object yang ingin kita konversi. Untuk memproses konversi juga tidak dibutuhkan CPU dan Memori tinggi. Walaupun demikian, file yang dihasilkan berbentuk binary, sehingga menyulitkan debugging.

JSON dan XML berbentuk text, sehingga mudah didebug kalau ada masalah. Walaupun demikian, kita harus membuat atau memilih dari yang ada implementasi generator dan parser untuk proses konversi. Proses konversinya butuh resource CPU dan memori. Dan yang paling penting, kita mungkin harus membuat generator/parser untuk tiap tipe data yang akan kita kirim.

Sementara saya pilih JSON, karena ada json-lib yang bisa mengkonversi object menjadi JSON dan sebaliknya dengan mudah.

Selanjutnya, bagaimana cara mengirim email?

Cara mengirim email dengan Java sudah ditunjukkan Ifnu di sini. Tapi saya tidak mau coding tangan kosong seperti itu. Bukan apa-apa, setiap baris kode yang kita tulis harus ditest dan dimaintain. Belum lagi kalo nanti ada perubahan requirement, bisa coding ulang.

Nah, pertama saya memutuskan menggunakan Spring untuk mengirim email. Ibaratnya kalau coding sendiri itu berkelahi dengan tangan kosong, pakai Spring berkelahi pakai pistol. Jauh lebih cepat dan mudah.

Tapi ternyata, pistol juga tidak cukup, karena kita belum bisa menerima email. Bisa kirim gak bisa terima ya percuma, karena di sisi kantor cabang kita tentu harus mengambil dan memproses data yang dikirim dari pusat. Ifnu sebetulnya sudah membuat implementasi penerima emailnya, tapi nampaknya belum diposting.

Saatnya membuka gudang senjata dan mencari senjata yang lebih besar. Saya menemukan rocket launcher, yaitu Spring Integration.

Bukan saja bisa menerima email, Spring Integration juga bisa menggunakan semua alternatif transport yang disebutkan di atas (WS, HTTPInvoker, RMI, FTP, SSH, JMS, Email) hanya dengan mengganti beberapa baris konfigurasi. Wow …. canggih sekali. Baiklah, saya akan pakai ini saja.

Berhubung artikel ini sudah terlalu panjang. Implementasi Spring Integrationnya diteruskan di bagian kedua.


Mengakses EJB secara Remote

Mengakses EJB secara Remote

Beberapa buku tentang EJB, seperti EJB 3 in Action karangan Reza Rahman maupun Enterprise Java Beans 3.0 karangan Bill Burke, membahas secara detail tentang penggunaan EJB. Akan tetapi, ada satu hal kecil namun penting yang tidak dibahas. Bagaimana cara mengakses EJB secara remote?

Di sisi server, ini mudah. Cukup membuat remote interface saja beres. Tapi bagaimana cara lookupnya dari client? Artikel ini akan membahas cara memanggil EJB dari method main.

Sebelumnya, berikut adalah EJB yang akan kita panggil.

HaloBean.java

package com.artivisi.belajar.ejb.session;

@Stateless
public class HaloBean implements HaloRemote {
   public String halo(String nama) {
     return "Halo "+nama;
   }
}

HaloRemote.java

package com.artivisi.belajar.ejb.session;

@Remote
public interface HaloRemote {
   public String halo(String nama);
}

EJB ini akan kita deploy ke Glassfish menggunakan Netbeans. Bagaimana caranya? Silahkan buka menu Help Netbeans.

Berikut adalah kode untuk memanggil HaloBean secara remote.

HaloClient.java

package com.artivisi.belajar.ejb.client;

public class HaloClient {
  public static void main(String[] args){
    // 0. Konfigurasi host dan port
    String ejbHost = "localhost";
    String ejbPort = 12345;
    String ejbName = HaloRemote.class.getName();
  
    // 1. JNDI Context
    Properties props = new Properties();
    props.put("org.omg.CORBA.ORBInitialHost", ejbHost);
    props.put("org.omg.CORBA.ORBInitialPort", ejbPort);
    
    InitialContext ctx = new InitialContext(props);
    
    // 2. Lookup EJB
    HaloRemote haloBean = (HaloRemote) ctx.lookup(ejbName);
    
    // 3. Panggil methodnya
    System.out.println("Halo EJB : "+haloBean.halo("endy"));
  }
}

Ada beberapa variabel yang perlu diperhatikan di sini, yaitu ejbHost, ejbPort, dan ejbName. Variabel ejbHost tentunya adalah komputer tempat EJB dideploy. Variabel ejbPort adalah port yang digunakan oleh Application Server untuk mempublish EJB. Port ini berbeda-beda tergantung merek application server dan cara deploymentnya. Karena saya menggunakan Netbeans untuk mendeploy ke Glassfish, maka saya harus cari tahu dulu berapa port yang digunakan Netbeans.

Caranya, login ke admin console Glassfish melalui Netbeans. Buka tab Services, klik kanan Glassfish, dan pilih View Admin Console. (/images/uploads/2009/06/netbeans-view-admin-console.png) Browser akan terbuka dan menampilkan halaman login Glassfish. (/images/uploads/2009/06/glassfish-login.png) Setelah login, klik Application Server di panel kiri. Port yang digunakan akan ditampilkan di panel kanan, yaitu dengan nama IIOP Port(s). Coba-coba saja semuanya. Di komputer saya, port yang benar adalah 10275. (/images/uploads/2009/06/glassfish-iiop-port.png) Variabel ejbName juga berbeda tergantung dari application server yang digunakan. Baca dokumentasi server Anda untuk memastikannya.


Backup MySQL

Sebelumnya, saya telah membahas script backup untuk Trac maupun Subversion. Kali ini, kita akan bahas backup script untuk MySQL.

Sama seperti backup script sebelumnya, script ini akan membuat folder sesuai dengan tanggal dan jam backup. Selanjutnya, script akan melakukan backup terhadap database MySQL sesuai dengan nama database yang ditentukan. Backup ini akan disimpan di folder yang kita tentukan.

Berikut backup scriptnya.

[Update - 7 Des 2009] Sudah ditambahkan perintah untuk kompresi hasil backupnya.

#!/bin/sh

test -x /bin/date || exit -1
test -x /usr/bin/mysqldump || exit -1
test -x /bin/tar || exit -1
test -x /bin/bzip2 || exit -1

DBHOST=$1
DBNAME=$2
USERNAME=$3
PASSWORD=$4
BACKUP_FOLDER=$5
CURR_DATE="$(/bin/date +%Y%m%d-%H%M)"


if [ "$1" = '' ]; then
    echo "Usage : $0 <db name> <username> <password> <backup folder>"
    return 1
fi

if [ "$2" = '' ]; then
    echo "Usage : $0 <db name> <username> <password> <backup folder>"
    return 1
fi

if [ "$3" = '' ]; then
    echo "Usage : $0 <db name> <username> <password> <backup folder>"
    return 1
fi

if [ "$4" = '' ]; then
    echo "Usage : $0 <db name> <username> <password> <backup folder>"
    return 1
fi


echo "Create backup folder $BACKUP_FOLDER/$CURR_DATE"
echo "..."

/bin/mkdir "$BACKUP_FOLDER/$CURR_DATE"

echo "Backup $DBNAME schema to $BACKUP_FOLDER/$CURR_DATE/$DBNAME-schema-$CURR_DATE.sql"
echo "..."

/usr/bin/mysqldump $DBNAME -u $USERNAME -p$PASSWORD -h$DBHOST -d > "$BACKUP_FOLDER/$CURR_DATE/$DBNAME-schema-$CURR_DATE.sql"

echo "Backup $DBNAME data to $BACKUP_FOLDER/$CURR_DATE/$DBNAME-data-$CURR_DATE.sql"
echo "..."

/usr/bin/mysqldump $DBNAME -u $USERNAME -p$PASSWORD -h $DBHOST -n -c -t --single-transaction > "$BACKUP_FOLDER/$CURR_DATE/$DBNAME-data-$CURR_DATE.sql"

echo "Compressing folder $CURR_DATE"
echo "..."

/bin/tar cvf - "$BACKUP_FOLDER/$CURR_DATE" | /bin/bzip2 -c9 > "$BACKUP_FOLDER/$CURR_DATE.tar.bz2"

echo "Removing folder $BACKUP_FOLDER/$CURR_DATE"
echo "..."

/bin/rm -rf "$BACKUP_FOLDER/$CURR_DATE"

echo "Completed"

Script di atas dapat dijalankan setiap Jumat malam jam 23.00 dengan konfigurasi sebagai berikut.

0 23 * * 5 /bin/sh /path/ke/mysql-backup.sh db_user db_pass db_name backup_folder_mysql

SSH dengan JSch

Mengakses Remote Server dengan Java

Kita sudah biasa mengakses komputer lain menggunakan SSH. Cukup ketikkan ssh username@namaserver, tekan enter, dan lakukan apa yang kita mau. Nah, bagaimana kalau kita ingin membuat aplikasi yang butuh mengakses komputer lain? Misalnya, kita ingin membuat aplikasi sederhana yang menampilkan input IP Address, Username, Password serta tombol Shutdown. Begitu input field kita isi dan tombol Shutdown ditekan, aplikasi kita akan melakukan ssh ke komputer tersebut dan menjalankan perintah shutdown -h now.

Di Java, hal ini dapat dengan mudah dilakukan menggunakan pustaka JSch. Berikut langkah-langkah untuk menggunakan JSch.

Mendapatkan Pustaka JSch

Tentunya yang pertama kita lakukan adalah membuka website JSch dan mengunduh rilis terbaru. Pilih yang ZIP, jangan yang JAR, karena di dalamnya ada beberapa contoh penggunaan yang akan kita butuhkan untuk mencontek nantinya.

Paket ZIP ini belum dikompilasi, dan kita membutuhkan Ant untuk melakukan proses build. Jika Anda belum pernah menggunakan Ant, baca dulu tutorial ini. Setelah proses build selesai dilakukan, akan muncul file *jar di dalam folder dist.

Template Aplikasi Java

Buatlah project Java menggunakan editor yang Anda sukai. Pastikan jar JSch sudah terdaftar di project Java yang barusan dibuat. Setelah itu, buatlah Java Class sebagai berikut

public class JschDemo {
    public static void main(String[] args) throws Exception {

    }
}

Untuk selanjutnya, kode program akan ditulis di dalam method main.

Parameter koneksi

Untuk melakukan koneksi ke komputer lain, kita memerlukan beberapa variabel, ditunjukkan dengan kode sebagai berikut.

String host = "localhost";
String user = "endy";
String pass = "java";
String command = "shutdown -h now";

Kita akan melakukan koneksi ke komputer kita sendiri (localhost) dengan username endy dan password java. Setelah berhasil terhubung, kita akan menjalankan perintah shutdown -h now.

Pre Requisite

Agar kode program kita bisa dijalankan, ada beberapa persyaratan sebagai berikut:

  • Komputer yang ingin dihubungi harus menjalankan SSH server

  • Komputer yang ingin menghubungi harus melakukan koneksi SSH secara manual terlebih dulu, agar komputer tujuan terdaftar di file known_hosts

  • User yang digunakan untuk koneksi harus memiliki akses yang cukup untuk melakukan perintah yang diinginkan

Menggunakan JSch

Setelah parameter koneksi kita deklarasikan, dan juga prasyarat di komputer tujuan dipenuhi, sekarang kita bisa mulai menggunakan JSch. Pertama, kita instankan dulu object dari class JSch.

JSch jsch = new JSch();

Kemudian, kita berikan database known_hosts, yaitu daftar komputer tujuan beserta public keynya. Ini berguna untuk melakukan verifikasi terhadap komputer tujuan.

jsch.setKnownHosts("/home/endy/.ssh/known_hosts");

File known_hosts ini akan otomatis dibuat bila kita melakukan koneksi SSH ke komputer lain. Itulah sebabnya kita harus melakukan koneksi manual terlebih dulu, sehingga public key komputer tujuan sudah terdaftar dalam file ini. Alternatif dari menggunakan file ini adalah mendaftarkan public key di komputer tujuan dan menggunakan private key untuk login.

Selanjutnya, kita membuka koneksi ke komputer tujuan

Session session = jsch.getSession(user, host);
session.setPassword(pass);
session.connect();

Lalu, kita membuka channel. Channel menggambarkan bentuk interaksi kita dengan komputer tujuan. JSch menyediakan beberapa jenis channel, misalnya exec dan shell. Kita menggunakan exec untuk mengeksekusi satu perintah saja. Sedangkan shell bisa digunakan untuk membuka terminal interaktif yang bisa kita berikan perintah sebanyak kita mau.

ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
channel.connect();

Kita bisa membaca output dari perintah yang kita jalankan menggunakan I/O Stream seperti biasa.

BufferedReader reader = new BufferedReader(new InputStreamReader(channel.getInputStream()));
String output = reader.readLine();
while (output != null) {
    System.out.println(output);
    output = reader.readLine();
}
reader.close();

Segera setelah perintah selesai dijalankan, kita mengakhiri channel dan session.

channel.disconnect();
session.disconnect();

Berikut adalah keseluruhan kode program.

public class JschDemo {

    public static void main(String[] args) throws Exception {
	String host = "localhost";
	String user = "endy";
	String pass = "java";
	String command = "shutdown -h now";

        JSch jsch = new JSch();
        jsch.setKnownHosts("/home/endy/.ssh/known_hosts");

        Session session = jsch.getSession(user, host);
        session.setPassword(pass);
        session.connect();

        ChannelExec channel = (ChannelExec) session.openChannel("exec");
        channel.setCommand(command);
        channel.connect();

        BufferedReader reader = new BufferedReader(new InputStreamReader(channel.getInputStream()));
        String output = reader.readLine();
        while (output != null) {
            System.out.println(output);
            output = reader.readLine();
        }
        reader.close();

        channel.disconnect();
        session.disconnect();

    }
}

Selamat mencoba. Bila percobaan Anda sukses, komputer yang sedang Anda gunakan akan shutdown setelah aplikasi selesai dijalankan. :D


Upgrade Ubuntu

Sebentar lagi Ubuntu terbaru akan rilis. Seperti biasanya, saya akan menjalankan ritual 6 bulanan yang terdiri dari kegiatan sbb:

  • Unduh ISO Ubuntu terbaru

  • Bakar ke CD

  • Backup isi home folder

  • Backup mailbox Thunderbird

  • Remove semua hidden file di home folder

  • Reinstall Ubuntu dengan memformat partisi sistem

Saya tidak terlalu suka upgrade, karena banyak menyisakan sampah dan jebakan. Lebih nyaman dan cepat memformat partisi sistem daripada troubleshoot hasil upgrade.

Karena ritual ini akan terus dilakukan di masa depan, ada baiknya kita optimasi workflownya agar lebih efisien.

Berikut adalah requirement saya untuk workflow upgrade ini:

  • Saya memiliki beberapa aplikasi yang mandatory tapi tidak termasuk dalam paket default Ubuntu, seperti Java SDK, Thunderbird, Inkscape, dan beberapa aplikasi lain. Saya ingin menyimpan daftar aplikasi ini, dan me-reuse-nya setiap kali upgrade.

  • Saya ingin memisahkan proses download *.deb yang memakan waktu lama dengan proses instalasi aplikasi. Tujuannya, agar proses download *.deb ini bisa ‘dititipkan’ di komputer lain yang online 24/7. Setelah selesai, hasilnya tinggal dicopy ke komputer saya, dan langsung diinstal

Setelah browsing kesana kemari, akhirnya saya mendapatkan workflow yang sesuai, sebagai berikut.

  • Buat dulu daftar paket yang ingin diinstal, dari instalasi Ubuntu yang sekarang

  • Lakukan proses instalasi

  • Buat daftar URL untuk mengunduh *.deb menggunakan Ubuntu yang baru diinstal

  • Jalankan proses unduh di komputer lain yang online 24/7

  • Setelah selesai, pindahkan hasilnya ke komputer ber-Ubuntu baru, dan instal

Membuat daftar aplikasi

Daftar aplikasi yang terinstal di komputer yang kita pakai sekarang dapat didapatkan dengan menjalankan perintah berikut di command prompt.

dpkg --get-selections | sed -n 's/^\(.*\)\tinstall$/\1$/p' | cut -f1 > daftar_aplikasi.txt

Buka file daftar_aplikasi.txt dengan Text Editor dan buang aplikasi yang terinstal secara default. Setelah diedit, file saya berisi sebagai berikut.

ttf-inconsolata
ttf-droid
nautilus-open-terminal
mc
chmsee
unrar
comix
keepassx
subversion
git-svn
gimp
network-manager-openvpn
network-manager-openvpn-gnome
network-manager-pptp
network-manager-pptp-gnome
network-manager-vpnc
network-manager-vpnc-gnome
openssh-server
gnome-alsamixer
vlc
rtorrent
hamster-applet
timer-applet
inkscape
mysql-server
mysql-query-browser
mysql-admin
sun-java6-jdk
ubuntu-restricted-extras
build-essential
ant

Proses Instalasi

Tidak ada yang istimewa dari proses instalasi. Berikut checklist yang saya gunakan:

  • Backup isi home folder

  • Backup mailbox Thunderbird, biasanya ada di folder .mozilla-thunderbird

  • Remove semua hidden file dan folder di home. File hidden ini berisi konfigurasi aplikasi yang terinstal. Kita tidak ingin sistem baru kita menggunakan konfigurasi lama. Nanti jadi tidak terlihat barunya.

  • Reinstall Ubuntu dengan memformat partisi sistem

  • Edit /etc/apt/sources.list agar menggunakan mirror lokal. Saya biasa menggunakan kambing.ui.ac.id

  • Jalankan apt-get update untuk mengupdate database aplikasi

Berikut isi file /etc/apt/sources.list saya.

deb http://kambing.ui.ac.id/ubuntu/ intrepid main restricted universe multiverse
deb http://kambing.ui.ac.id/ubuntu/ intrepid-updates main restricted universe multiverse
deb http://kambing.ui.ac.id/ubuntu/ intrepid-security main restricted universe multiverse

Setelah install ulang, file ini akan menjadi seperti ini

deb http://kambing.ui.ac.id/ubuntu/ jaunty main restricted universe multiverse
deb http://kambing.ui.ac.id/ubuntu/ jaunty-updates main restricted universe multiverse
deb http://kambing.ui.ac.id/ubuntu/ jaunty-security main restricted universe multiverse

Segera setelah database aplikasi kita up-to-date, kita bisa lanjut ke langkah berikutnya.

Membuat daftar URL untuk download

Jalankan perintah berikut di command prompt.

cat daftar_aplikasi.txt |  tr '\n' ' '| xargs apt-get install -qq --print-uris | cut -d\' -f2 > daftar_url.txt

Perintah ini akan menghasilkan file daftar_url.txt, yang berisi daftar URL file *.deb yang dibutuhkan untuk instalasi.

Mengunduh *.deb

Berbekal daftar_url.txt, kita bisa segera menjalankan proses pengunduhan di komputer lain yang online 24/7. Komputer ini tidak perlu menjalankan Ubuntu terbaru. Bahkan tidak harus menjalankan Linux.

Jika komputer tersebut juga menjalankan Linux, maka kita bisa menggunakan wget dengan perintah sebagai berikut.

wget -b -c -nc -o donlod-ubuntu.log -i daftar_url.txt

Proses pengunduhan dapat dipantau dengan melihat isi file donlod-ubuntu.log. Gunakan perintah tail seperti ini.

tail -f donlod-ubuntu.log 

Tekan Ctrl+C untuk keluar dari tail.

Proses ini akan menghasilkan banyak file *.deb di folder tempat kita menjalankan perintah wget tadi. Setelah semua file didapatkan, copy ke komputer kita yang baru diinstal tersebut.

Instalasi *.deb

Copy semua file *.deb ke folder /var/cache/apt/archives di komputer berUbuntu baru. Selanjutnya kita lakukan proses instalasi dengan mengetik perintah berikut di command prompt.

cat daftar_aplikasi.txt  |  tr '\n' ' '| xargs apt-get install -y

Tunggu sejenak sampai selesai.

Replikasi Instalasi

Bagaimana jika kita disuruh melakukan instalasi identik di banyak komputer sekaligus? Gampang, berikut caranya.

Instal salah satu komputer sampai selesai. Lengkapi semua aplikasi yang dibutuhkan. Segera setelah selesai, extract daftar aplikasi yang terinstal menggunakan perintah berikut.

dpkg --get-selections > daftar_instalasi.txt

Copy file daftar_instalasi.txt ini berikut isi folder /var/cache/apt/archives/ ke komputer berikut yang akan diinstal.

Di komputer berikut, copy file *.deb ke folder /var/cache/apt/archives/. Lalu jalankan perintah berikut untuk mengisi daftar instalasi.

sudo dpkg --set-selections < daftar_instalasi.txt

Setelah itu, jalankan perintah berikut untuk memulai proses instalasi.

sudo apt-get dselect-upgrade

Semoga bermanfaat.