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.

Cruise Control

Kalau Anda programmer Java, tentunya sudah tidak asing lagi dengan Tomcat atau Eclipse. Yang satu adalah application server, satunya lagi adalah Integrated Development Environment (IDE). Ada satu kesamaan dalam kedua produk ini, keduanya adalah proyek open source yang dikelola secara profesional.

Coba buka halaman download di website masing-masing proyek tersebut. Di sana bisa kita temukan beberapa jenis download, yaitu Nightly Builds dan Stable Builds. Stable builds adalah aplikasi yang sudah melalui berbagai fase testing dan dinyatakan lulus uji. Nightly builds, seperti namanya, adalah build yang dibuat setiap malam dan dirilis kepada publik agar bisa diuji coba beramai-ramai. Dengan besarnya jumlah penguji, diharapkan bug yang ada dalam aplikasi bisa ditemukan semuanya.

Build, dalam dunia Java, terdiri dari serangkaian aktifitas, diantaranya sebagai berikut:

  1. Menjalankan review kode otomatis

  2. Kompilasi kode program

  3. Menjalankan unit test

  4. Menjalankan integration test

  5. Menjalankan coverage test (kalau ada)

  6. Menjalankan platform test, untuk aplikasi yang berbeda antar OS (seperti Eclipse)

  7. Bila lulus semua ujian di atas, buat tag di version control

  8. Siapkan executable (*.jar, *.war, *exe, dan sebagainya)

  9. Publish executable di website supaya bisa didownload orang banyak

Wow, daftar aktifitasnya cukup banyak. Kalau ini dikerjakan setiap malam, betapa membosankan. Saya tidak dapat membayangkan ada satu orang yang ditugaskan khusus untuk melakukan hal ini. Pasti setelah beberapa hari saja dia akan bosan dan mengundurkan diri. Apalagi dalam project open source di mana sebagian besar kontributornya tidak dibayar.

Untuk itulah ada tools khusus untuk melakukan hal membosankan ini. Toolsnya disebut Continuous Integration Tools, berdasarkan tulisan Martin Fowler tentang Continuous Integration. Ada beberapa tools yang tersedia di pasaran, diantaranya:

Dalam tulisan kali ini, kita akan bahas tentang penggunaan CruiseControl, salah satu Continuous Integration Tool yang populer dan open source.

CI Tool yang baik haruslah memiliki fitur sebagai berikut:

  • Mendukung berbagai jenis version control, minimal Subversion dan CVS

  • Dapat menggunakan Ant atau Maven

  • Mendukung banyak project

  • Dapat mengelola artifact (hasil build)

  • Dapat memberitahu orang tentang hasil build (gagal atau sukses) melalui berbagai cara (email, instant message, sms, dan sebagainya)

  • Memiliki aplikasi pelaporan yang mudah diakses melalui web

Yang dilakukan oleh CI Tools adalah sebagai berikut:

  1. Periksa repository source code, apakah ada perubahan terbaru

  2. Bila ada, ambil perubahan terbaru tersebut

  3. Lakukan build (compile, testing, dsb)

  4. Laporkan hasilnya (gagal atau berhasil) melalui email atau media lainnya

  5. Buat juga laporan di website

  6. Bila sukses, publish artifact yang dihasilkan

Cruise Control membutuhkan beberapa file konfigurasi:

  • config.xml: Hanya satu, digunakan untuk mendaftarkan project yang akan dikelola

  • build-namaproject.xml : Satu per project. Bila kita punya tiga project, maka akan ada tiga build-namaproject.xml, dengan nama file disesuaikan dengan masing-masing project.Buildfile ini bertugas untuk sinkronisasi dengan version control dan membuat tag di version control

  • build.xml : Satu per project. Ini adalah buildfile yang biasa kita gunakan di project untuk melakukan kompilasi, menjalankan test, dan menghasilkan *jar atau *war.

Kita butuh satu folder kerja untuk CruiseControl melakukan tugasnya. Sebaiknya folder ini dipisahkan dari folder instalasi CruiseControl agar memudahkan kita pada waktu melakukan upgrade CruiseControl. Untuk kepentingan ilustrasi, folder instalasi CruiseControl akan ditulis [CC_INSTALL] dan folder kerja akan ditulis [CC_WORK].

Berikut adalah struktur folder [CC_INSTALL]:

Struktur Folder Instalasi CruiseControl

dan folder kerja [CC_WORK] akan berisi seperti ini:

Folder Kerja CruiseControl

Struktur folder di dalam repository Subversion kita seperti ini:

Struktur Folder Subversion

Pada contoh ini, kita akan menjalankan build untuk satu project TestingTraining dengan konfigurasi sebagai berikut:

  1. Memiliki dua build, yang satu berjalan setiap satu menit, satu lagi berjalan setiap jam 18.00 sore

  2. Version control yang digunakan adalah Subversion

  3. Bila build sukses, buat tag di folder releases/daily-build/build-NN-yyyyMMddhhmmss

Konfigurasi tersebut ditulis di config.xml sebagai berikut.

<cruisecontrol>
    <project name="TestingTraining" buildafterfailed="true">
      <listeners>
        <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
      </listeners>

      <modificationset quietperiod="10">
          <svn RepositoryLocation="svn://172.16.2.252/trunk" />
      </modificationset>

      <schedule interval="60">
          <ant anthome="/opt/apache-ant-1.6.5"
               antWorkingDir="/home/endy/tmp/cruise-work/projects/${project.name}"
               buildfile="/home/endy/tmp/cruise-work/build-${project.name}.xml"
               target="build"
               uselogger="true"
               usedebug="false"
	       />
      </schedule>

      <log>
          <merge dir="/home/endy/tmp/cruise-work/projects/${project.name}/build/report/junit"/>
      </log>

      <publishers>
            <onsuccess>
                <antpublisher anthome="/opt/apache-ant-1.6.5"
                              antWorkingDir="/home/endy/tmp/cruise-work/projects/${project.name}"
                              buildfile="/home/endy/tmp/cruise-work/build-${project.name}.xml"
                            target="tag"
                            uselogger="true"
                            usedebug="false"
                />
		<artifactspublisher
		    dir="/home/endy/tmp/cruise-work/projects/${project.name}/dist"
		    dest="artifacts/${project.name}"/>
            </onsuccess>
        </publishers>
    </project>
</cruisecontrol>

Berikut adalah penjelasannya.

  • Konfigurasi CruiseControl dibuat dengan format XML. Tag paling luar adalah <cruisecontrol>

  • Satu file konfigurasi bisa memuat banyak project. Masing-masing project dikonfigurasi dalam tag <project>

  • Di halaman depan CruiseControl, akan ada status untuk masing-masing project. Status ini akan disimpan di file status.txt

  • Modification Set: Beberapa produk version control tidak mengenal atomic commit, misalnya CVS. Karena itu, bila kita commit (misalnya) 7 file sekaligus, bisa saja CruiseControl terbangun pada saat baru 3 file yang tercommit. Bila CruiseControl melakukan build pada saat itu juga, bisa dipastikan akan terjadi error. Oleh karena itu, kita suruh CruiseControl membatalkan build bila kurang dari 10 detik yang lalu ada orang yang commit. Tentu saja bila kita menggunakan Subversion, hal ini tidak relevan.

  • Schedule: Ini adalah daftar build schedule yang ingin kita daftarkan. Tag ini bisa memuat banyak build. Kita menggunakan interval 60 detik, yang artinya setiap menit CruiseControl akan melakukan build. Selain schedule yang berbasis interval, kita juga bisa mendaftarkan schedule yang menggunakan waktu tertentu, misalnya berjalan setiap jam 12 malam.

  • Merge log yang dihasilkan JUnit, tersimpan di folder build/report/junit ke dalam tampilan report CruiseControl.

  • Publisher : pada bagian ini kita daftarkan Ant Publisher pada kategori onsuccess. Artinya, kalau build sukses, jalankan target tag untuk membuat tag di dalam repository. Selain itu, kita juga menggunakan Artifact Publisher, yang berguna untuk mengkopi file *.jar yang dihasilkan ke dalam folder CruiseControl sehingga bisa didownload melalui website.

Di file konfigurasi tersebut, kita memanggil file build-TestingTraining.xml. Ini adalah isi dari file tersebut.

<project name="CruiseControl Builder"
    	 default="build"
         basedir="projects/TestingTraining">

  <property name="repository.url" value="svn://localhost"/>
  <property name="branch" value="trunk"/>
  <property name="release.folder" value="releases/daily-build" />
  <property name="svn.username" value="endy" />
  <property name="svn.password" value="123" />
  <property name="message" value="Created automatically by CruiseControl" />

  <path id="cc-classpath">
    <fileset dir="../../lib" includes="**/*jar"/>
  </path>  

  <target name="update">
    <java classname="org.tmatesoft.svn.cli.SVN" fork="true"
          classpathref="cc-classpath">
      <arg value="update"/>      
    </java>
  </target>

  <target name="build" depends="update">
    <ant inheritAll="false" target="build-jar"/>
  </target>

  <target name="tag">
    <java classname="org.tmatesoft.svn.cli.SVN"
              fork="true" classpathref="cc-classpath">
            <arg value="--username"/>
            <arg value="${svn.username}"/>

            <arg value="--password"/>
            <arg value="${svn.password}"/>

            <arg value="cp"/>
            <arg value="${repository.url}/${branch}"/>
            <arg value="${repository.url}/${release.folder}/${label}-${cctimestamp}"/>

            <arg value="-m"/>
            <arg value="${message}"/>

        </java>
  </target>

</project>

Penjelasannya sebagai berikut.

  • Kita menggunakan pustaka yang disediakan SVNKit (dulunya JavaSVN) agar bisa menggunakan Subversion melalui Ant. Sebetulnya tanpa SVNKit juga bisa, yaitu dengan target exec yang dimiliki Ant untuk memanggil perintah di command line. Dengan menggunakan SVNKit, kita tidak perlu menginstal Subversion command line di build server kita.

  • Ada tiga target utama dalam buildfile ini: update, build, dan tag. Target update berguna untuk mengambil perubahan terbaru dari repository ke folder kerja CruiseControl. Target build memanggil target build-jar di dalam build.xml yang dimiliki project. Target build-jar ini hanya bisa berhasil kalau semua test sudah berjalan dengan sempurna. Target tag berguna untuk membuat tag di repository. Kita bisa mengirim variabel yang dihasilkan CruiseControl, dalam hal ini ${label} dan ${cctimestamp}.

Agar file ini bisa dijalankan, kita harus memiliki folder projects/TestingTraining yang berisi hasil checkout dari repository. Mari kita checkout dulu.

$ cd projects
$ svn co svn://localhost/trunk TestingTraining

Untuk menguji apakah file build-TestingTraining.xml ini bisa dijalankan dengan baik, masuk ke folder projects/TestingTraining dan panggil file tersebut dari folder ini.

$ ant -f ../../build-TestingTraining.xml build
Buildfile: ../../build-TestingTraining.xml

update:
     [java] At revision 71.

build:

clean:
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/build/bin
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/build/debug
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/build/cobertura
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/build/report/junit
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/build/report/pmd
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/build/report/cobertura
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/dist

prepare:
    [mkdir] Created dir: /home/endy/tmp/cruise-work/projects/TestingTraining/build/bin
    [mkdir] Created dir: /home/endy/tmp/cruise-work/projects/TestingTraining/build/debug
    [mkdir] Created dir: /home/endy/tmp/cruise-work/projects/TestingTraining/build/cobertura
    [mkdir] Created dir: /home/endy/tmp/cruise-work/projects/TestingTraining/build/report/junit
    [mkdir] Created dir: /home/endy/tmp/cruise-work/projects/TestingTraining/build/report/pmd
    [mkdir] Created dir: /home/endy/tmp/cruise-work/projects/TestingTraining/build/report/cobertura
    [mkdir] Created dir: /home/endy/tmp/cruise-work/projects/TestingTraining/dist

code-review:

compile:
    [javac] Compiling 11 source files to /home/endy/tmp/cruise-work/projects/TestingTraining/build/bin

compile-cobertura:
    [javac] Compiling 11 source files to /home/endy/tmp/cruise-work/projects/TestingTraining/build/debug
   [delete] Deleting: /home/endy/tmp/cruise-work/projects/TestingTraining/cobertura.ser
   [delete] Deleting directory /home/endy/tmp/cruise-work/projects/TestingTraining/build/cobertura
[cobertura-instrument] Cobertura 1.8 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[cobertura-instrument] Instrumenting 7 files to /home/endy/tmp/cruise-work/projects/TestingTraining/build/cobertura
[cobertura-instrument] Cobertura: Saved information on 7 classes.
[cobertura-instrument] Instrument time: 110ms

unit-test:
    [junit] Running tutorial.testing.CalculatorTest
    [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.047 sec
    [junit] Cobertura: Loaded information on 7 classes.
    [junit] Cobertura: Saved information on 7 classes.
    [junit] Running tutorial.testing.DayCounterTest
    [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.055 sec
    [junit] Cobertura: Loaded information on 7 classes.
    [junit] Cobertura: Saved information on 7 classes.
    [junit] Running tutorial.testing.LoginServletTest
    [junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.159 sec
    [junit] Cobertura: Loaded information on 7 classes.
    [junit] Cobertura: Saved information on 7 classes.
    [junit] Running tutorial.testing.dbunit.PersonDaoMySQLTest
    [junit] Tests run: 3, Failures: 0, Errors: 0, Time elapsed: 0.153 sec
    [junit] Cobertura: Loaded information on 7 classes.
    [junit] Cobertura: Saved information on 7 classes.
[junitreport] Transform time: 564ms
[cobertura-report] Cobertura 1.8 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[cobertura-report] Cobertura: Loaded information on 7 classes.
[cobertura-report] Report time: 231ms

coverage-test:
[cobertura-check] Cobertura 1.8 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[cobertura-check] Cobertura: Loaded information on 7 classes.
[cobertura-check] All checks passed.

full-test:

build-jar:
      [jar] Building jar: /home/endy/tmp/cruise-work/projects/TestingTraining/dist/TutorialTesting.jar

BUILD SUCCESSFUL
Total time: 12 seconds

File build-TestingTraining.xml akan memanggil build.xml yang ada di dalam project kita. Berikut isi dari file ini.

<project name="TestingTraining" default="full-test" basedir=".">

	<property name="source.java" value="src/java"/>
	<property name="compile.normal" value="build/bin"/>
	<property name="compile.debug" value="build/debug"/>
	<property name="compile.cobertura" value="build/cobertura"/>
	<property name="distribution" value="dist" />

	<property name="report.junit" value="build/report/junit"/>
	<property name="report.pmd" value="build/report/pmd"/>
	<property name="report.cobertura" value="build/report/cobertura"/>

	<path id="devel.classpath">
		<pathelement location="${source.java}"/>
		<pathelement location="${compile.debug}"/>
		<fileset dir="lib" includes="**/*jar" />
		<fileset dir="ext" includes="**/*jar" />
	</path>

	<taskdef classpathref="devel.classpath" resource="tasks.properties"/>

	<target name="prepare">
		<mkdir dir="${compile.normal}"/>
		<mkdir dir="${compile.debug}"/>
		<mkdir dir="${compile.cobertura}"/>
		<mkdir dir="${report.junit}"/>
		<mkdir dir="${report.pmd}"/>
		<mkdir dir="${report.cobertura}"/>

		<mkdir dir="${distribution}" />
	</target>

	<target name="clean">
		<delete dir="${compile.normal}"></delete>
		<delete dir="${compile.debug}"></delete>
		<delete dir="${compile.cobertura}"></delete>
		<delete dir="${report.junit}"></delete>
		<delete dir="${report.pmd}"></delete>
		<delete dir="${report.cobertura}"></delete>
		<delete dir="${distribution}"></delete>
	</target>

	<target name="code-review" depends="prepare">
		<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="devel.classpath"/>
    	<pmd targetjdk="1.5" shortFilenames="true" failonerror="true" failonruleviolation="true" rulesetfiles="pmd-ruleset.xml">                           
	      <formatter type="net.sourceforge.pmd.renderers.HTMLRenderer"
	                 toFile="${report.pmd}/pmd.html"
	      />
	      <fileset dir="${source.java}">
	          <include name="**/*.java"/>
	          <exclude name="**/*Test.java"/>
	      </fileset>
	    </pmd>
	</target>

	<target name="compile" depends="code-review">
		<javac
			srcdir="${source.java}"
			destdir="${compile.normal}"
			classpathref="devel.classpath">
		</javac>
	</target>

	<target name="unit-test" depends="compile,compile-cobertura">
		<junit haltonfailure="true" fork="true" printsummary="true">
			<classpath location="${compile.cobertura}"></classpath>
			<classpath refid="devel.classpath"/>
            <formatter type="xml"/>
            <batchtest todir="${report.junit}">
                <fileset dir="${compile.debug}" includes="**/*Test.class" excludes="**/*Abstract*.class"/>
            </batchtest>
		</junit>

		<junitreport todir="${report.junit}">
            <fileset dir="${report.junit}">
            <include name="TEST-*.xml"/>
            </fileset>
            <report format="frames" todir="${report.junit}/html"/>
        </junitreport>

		<cobertura-report
        	datafile="cobertura.ser"
        	srcdir="${source.java}"
        	destdir="${report.cobertura}"
        />
	</target>

	<target name="compile-cobertura" depends="prepare">
		<javac
			srcdir="${source.java}"
			destdir="${compile.debug}"
			classpathref="devel.classpath"
			fork="true"
			debug="true"
		/>
        <delete file="cobertura.ser"/>
    	<delete dir="${compile.cobertura}" />

        <cobertura-instrument todir="${compile.cobertura}">
            <fileset dir="${compile.debug}">
                    <include name="**/*.class"/>
                    <exclude name="**/*Test*.class"/>
            </fileset>
        </cobertura-instrument>
	</target>

	<target name="coverage-test" depends="unit-test">
		<cobertura-check datafile="cobertura.ser"
                         branchrate="75"
                         linerate="75"
                         haltonfailure="true"
        />

	</target>

	<target name="full-test" depends="code-review,coverage-test"></target>

	<target name="build-jar" depends="clean,full-test">
		<jar destfile="${distribution}/${ant.project.name}.jar"
		       basedir="${compile.normal}"
		       excludes="**/*Test.class"
		  />
	</target>
</project>

Seperti kita lihat di atas, file tersebut memiliki target build-jar yang hanya akan dilakukan apabila target code-review, compile, unit-test, coverage-test dilakukan dengan sukses.

Baiklah, persiapan sudah selesai, sekarang jalankan CruiseControl, dan lihat hasilnya. CruiseControl dijalankan melalui command prompt dengan mensuplai config.xml yang kita miliki.

$ cd [CC_INSTALL]
$ ./cruisecontrol.sh -configfile [CC_WORK]/config.xml

Bila tidak ada error, maka kita bisa browse ke http://localhost:8080

Ini adalah halaman depan. Memuat status masing-masing project.

Halaman Depan CruiseControl

Ini adalah halaman untuk TestingTraining.

Hasil Build

Seperti kita lihat, hasilnya build failed, karena database MySQL yang diperlukan untuk test belum dijalankan. Mari kita nyalakan dan buat test ini menjadi sukses. Setelah sukses, tampilannya seperti ini.

Hasil Build yang sukses

Kita bisa melihat hasil unit test di dalam tab Test Result.

Hasil JUnit

Berapa kali gagal, berapa kali sukses? Kita bisa lihat di tab Metric.

Metric tentang hasil build

Bila kita sudah menjalankan daily build ini selama beberapa waktu, di repository kita akan dihasilkan tag sesuai dengan build yang sukses. Berikut contohnya.

Daftar Tag yang dibuat CruiseControl

Demikianlah penggunaan CruiseControl. Dengan menggunakan CruiseControl ini, para programmer bisa dibebaskan dari tugas membosankan, sehingga waktunya bisa digunakan untuk hal lain yang lebih bermanfaat, seperti misalnya menulis blog atau menambah teman baru di Friendster.


Dual Head Ubuntu

Pertanyaan : Kalau kita punya komputer, upgrade hardware apa yang paling meningkatkan produktifitas ??

Jawaban 1 : Prosesor

Jawaban 2 : Memori

Saya tidak sependapat dengan kedua jawaban di atas. Prosesor lebih kencang atau memori memang meningkatkan kemampuan komputer. Tapi ada upgrade lain yang lebih signifikan efeknya, yaitu tambah monitor.

Anda pernah menonton film Swordfish? Film ini bercerita tentang Stanley Jobson, pensiunan hacker yang dipaksa membobol bank demi menyelamatkan anaknya. Di film ini, Stanley diberikan komputer super canggih agar bisa membobol jaringan bank. Komputer tersebut memiliki enam screen.

Mereka yang sudah pernah merasakan bekerja dengan dua (atau lebih) monitor pasti mengerti maksud saya. Bayangkan coding di satu screen dan melihat Java API di screen yang satu lagi. Atau membuat desain software (UML, ERD, dsb) di screen kanan sambil melihat dokumen analisa di screen kiri. Dan masih banyak kemungkinan lain yang bisa dilakukan. Bahkan Bill Gates bekerja dengan tiga monitor sekaligus.

Pada artikel ini, saya akan membahas tentang cara setup dua monitor di Ubuntu. Komputer yang saya gunakan adalah NEC Versa 3100. Walaupun berbeda di sisi teknis, cara ini juga bisa diterapkan di komputer lain yang menggunakan X.Org sebagai X servernya.

Sebelum mulai, mari kita kenali dulu istilah-istilah yang ada di dalam konfigurasi X.Org.

  • InputDevice : Ini adalah segala alat input seperti mouse, keyboard, touchscreen, pulpen elektronik, dan teman-temannya. Dalam satu file konfigurasi bisa dimasukkan banyak device.

  • Device: Yang dimaksud device di sini adalah display adapter kita, atau lebih dikenal dengan istilah VGA Card. Bila kita memasang lebih dari satu VGA Card, maka harus ada konfigurasi Device yang sesuai agar VGA Card tersebut bisa berfungsi dengan baik.

  • Monitor: Self Explanatory. Monitor adalah yang menampilkan output dari komputer.

Untuk mengaktifkan dual head, kita membutuhkan dua monitor. Perlu diperhatikan bahwa kita belum tentu butuh lebih dari satu VGA Card, tergantung tipe yang kita gunakan. Di PC saya yang lainnya, saya menggunakan NVidia GForce yang memiliki tiga output: VGA, DVI, dan TV. Yang biasa kita gunakan di monitor CRT adalah VGA port, sedangkan beberapa tipe monitor LCD biasanya menyediakan kabel VGA dan juga DVI. TV Out tentunya kita sudah tahu bentuknya, seperti colokan dari DVD player itu lho ..

Karena saya menggunakan notebook, maka saya memiliki dua output dari VGA, yang satu adalah LCD bawaan notebook tersebut, dan satu lagi VGA port yang biasa kita gunakan untuk presentasi.

Jumlah VGA dan output port yang kita miliki sangat penting diketahui agar bisa mengkonfigurasi dual head dengan benar. Untuk mereka yang VGA outputnya cuma satu port terpaksa pasang satu card lagi agar bisa menggunakan dual head.

Baiklah, mari kita masuk ke konfigurasi. Sebagai titik awal, berikut konfigurasi X.Org saya sebelum ada modifikasi apa-apa. Ini merupakan konfigurasi yang dibuatkan Ubuntu.

# /etc/X11/xorg.conf (xorg X Window System server configuration file)
#
# This file was generated by dexconf, the Debian X Configuration tool, using
# values from the debconf database.
#
# Edit this file with caution, and see the xorg.conf(5) manual page.
# (Type "man xorg.conf" at the shell prompt.)
#
# This file is automatically updated on xserver-xorg package upgrades *only*
# if it has not been modified since the last upgrade of the xserver-xorg
# package.
#
# If you have edited this file but would like it to be automatically updated
# again, run the following command:
#   sudo dpkg-reconfigure -phigh xserver-xorg

Section "Files"
	FontPath	"/usr/share/fonts/X11/misc"
	FontPath	"/usr/share/fonts/X11/cyrillic"
	FontPath	"/usr/share/fonts/X11/100dpi/:unscaled"
	FontPath	"/usr/share/fonts/X11/75dpi/:unscaled"
	FontPath	"/usr/share/fonts/X11/Type1"
	FontPath	"/usr/share/fonts/X11/100dpi"
	FontPath	"/usr/share/fonts/X11/75dpi"
	# path to defoma fonts
	FontPath	"/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
EndSection

Section "Module"
	Load	"i2c"
	Load	"bitmap"
	Load	"ddc"
	Load	"dri"
	Load	"extmod"
	Load	"freetype"
	Load	"glx"
	Load	"int10"
	Load	"vbe"
EndSection

Section "InputDevice"
	Identifier	"Generic Keyboard"
	Driver		"kbd"
	Option		"CoreKeyboard"
	Option		"XkbRules"	"xorg"
	Option		"XkbModel"	"pc105"
	Option		"XkbLayout"	"us"
EndSection

Section "InputDevice"
	Identifier	"Configured Mouse"
	Driver		"mouse"
	Option		"CorePointer"
	Option		"Device"		"/dev/input/mice"
	Option		"Protocol"		"ImPS/2"
	Option		"ZAxisMapping"		"4 5"
	Option		"Emulate3Buttons"	"true"
EndSection

Section "InputDevice"
	Identifier	"Synaptics Touchpad"
	Driver		"synaptics"
	Option		"SendCoreEvents"	"true"
	Option		"Device"		"/dev/psaux"
	Option		"Protocol"		"auto-dev"
	Option		"HorizScrollDelta"	"0"
EndSection

Section "InputDevice"
	Driver		"wacom"
	Identifier	"stylus"
	Option		"Device"	"/dev/input/wacom"
	Option		"Type"		"stylus"
	Option		"ForceDevice"	"ISDV4"		# Tablet PC ONLY
EndSection

Section "InputDevice"
	Driver		"wacom"
	Identifier	"eraser"
	Option		"Device"	"/dev/input/wacom"
	Option		"Type"		"eraser"
	Option		"ForceDevice"	"ISDV4"		# Tablet PC ONLY
EndSection

Section "InputDevice"
	Driver		"wacom"
	Identifier	"cursor"
	Option		"Device"	"/dev/input/wacom"
	Option		"Type"		"cursor"
	Option		"ForceDevice"	"ISDV4"		# Tablet PC ONLY
EndSection

Section "Device"
	Identifier	"Intel Corporation Mobile 915GM/GMS/910GML Express Graphics Controller"
	Driver		"i810"
	BusID		"PCI:0:2:0"
#	Option "ForceBIOS" "1920x1440=1280x768"
EndSection

Section "Monitor"
	Identifier	"Generic Monitor"
	Option		"DPMS"
EndSection

Section "Screen"
	Identifier	"Default Screen"
	Device		"Intel Corporation Mobile 915GM/GMS/910GML Express Graphics Controller"
	Monitor		"Generic Monitor"
	DefaultDepth	24
	SubSection "Display"
		Depth		1
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		4
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		8
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		15
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		16
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		24
		Modes		"1280x768"
	EndSubSection
EndSection

Section "ServerLayout"
	Identifier	"Default Layout"
	Screen		"Default Screen"
	InputDevice	"Generic Keyboard"
	InputDevice	"Configured Mouse"
	InputDevice     "stylus"	"SendCoreEvents"
	InputDevice     "cursor"	"SendCoreEvents"
	InputDevice     "eraser"	"SendCoreEvents"
	InputDevice	"Synaptics Touchpad"
EndSection

Section "DRI"
	Mode	0666
EndSection

Perlu saya ingatkan untuk SELALU BACKUP konfigurasi awal Anda sebelum mengubah konfigurasi. Jadi bila terjadi kegagalan, kita selalu bisa kembali ke setting awal.

Penggantian Nama

Pertama, mari kita ganti dulu beberapa nama pada file konfigurasi di atas agar lebih mudah dimengerti. Yang perlu diganti adalah bagian Monitor dan Device. Saya ganti menjadi seperti ini.

Section "Device"
	Identifier	"Intel i915 LCD Output"
	Driver		"i810"
	BusID		"PCI:0:2:0"
#	Option "ForceBIOS" "1920x1440=1280x768"
EndSection

Section "Monitor"
	Identifier	"Default LCD"
	Option		"DPMS"
EndSection

Artinya, device di atas mengacu pada output yang menuju LCD screen saya. Nama monitor juga diganti menjadi LCD agar lebih jelas.

Menambah Monitor

Sekarang, kita tambah monitor dan juga port VGA output. Konfigurasinya adalah sebagai berikut.

Section "Device"
	Identifier	"Intel i915 External Output"
	Driver		"i810"
	BusID		"PCI:0:2:0"
	Option "ForceBIOS" "1920x1440=1280x768"
EndSection
Section "Monitor"
	Identifier	"External Monitor"
	Option		"DPMS"
EndSection

Karena ada tambahan output, kita perlu menjelaskan pada X.Org mana screen utama kita. Kalau kita tidak lakukan ini, maka bisa saja pada saat booting LCD screen saya blank, karena outputnya dikeluarkan ke monitor CRT yang belum tentu dipasang. Tambahkan nomor screen pada konfigurasi VGA Card seperti ini.

Section "Device"
	Identifier	"Intel i915 LCD Output"
	Driver		"i810"
	BusID		"PCI:0:2:0"
#	Option "ForceBIOS" "1920x1440=1280x768"
	Option "MonitorLayout" "CRT,LFP"
	Screen		0
EndSection
Section "Device"
	Identifier	"Intel i915 External Output"
	Driver		"i810"
	BusID		"PCI:0:2:0"
	Option "ForceBIOS" "1920x1440=1280x768"
	Screen		1
EndSection

Dari konfigurasi di atas dapat terlihat bahwa screen utama (screen 0) adalah LCD Output. Di atas juga ada tambahan konfigurasi MonitorLayout. Ini ditambahkan agar secara default kedua output langsung aktif. Biasanya kalau kita pakai laptop, ada kombinasi tombol untuk mengaktifkan VGA Output, misalnya Fn+F5 atau Fn+F3. Nah, dengan opsi ini, VGA output langsung aktif tanpa harus menekan Fn+Something.

Konfigurasi Screen

Selanjutnya, kita akan mengkonfigurasi Screen. Screen adalah kombinasi antara Device dan Monitor. Artinya, konfigurasi ini akan menentukan VGA Output mana yang terhubung ke Monitor mana, berikut resolusi tampilannya. Karena tadi kita mengganti nama monitor dan VGA Output, maka kita harus sesuaikan konfigurasi Screen yang sudah ada. Berikut hasilnya.

Section "Screen"
	Identifier	"Default Screen"
	Device		"Intel i915 LCD Output"
	Monitor		"Default LCD"
	DefaultDepth	24
	SubSection "Display"
		Depth		1
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		4
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		8
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		15
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		16
		Modes		"1280x768"
	EndSubSection
	SubSection "Display"
		Depth		24
		Modes		"1280x768"
	EndSubSection
EndSection

dan selanjutnya, ini adalah tambahan untuk screen kedua kita.

Section "Screen"
	Identifier	"External Screen"
	Device		"Intel i915 External Output"
	Monitor		"External Monitor"
	DefaultDepth	24
	SubSection "Display"
		Depth		1
		Modes		"1024x768" "800x600"
	EndSubSection
	SubSection "Display"
		Depth		4
		Modes		"1024x768" "800x600"
	EndSubSection
	SubSection "Display"
		Depth		8
		Modes		"1024x768" "800x600"
	EndSubSection
	SubSection "Display"
		Depth		16
		Modes		"1024x768" "800x600"
	EndSubSection
	SubSection "Display"
		Depth		16
		Modes		"1024x768" "800x600"
	EndSubSection
	SubSection "Display"
		Depth		24
		Modes		"1024x768" "800x600"
	EndSubSection
EndSection

Kedua screen siap digunakan. Sekarang tinggal satu langkah terakhir.

ServerLayout

Kita perlu memberitahu X.Org screen mana yang ada di kiri, dan mana yang sebelah kanan. Gunanya agar mouse pointer kita bisa ‘menembus batas’ dengan benar. Misalnya monitor CRT kita pasang di sebelah kiri laptop, maka seharusnya kalau mouse pointer digerakkan ke pinggir kiri LCD, dia akan muncul di pinggir kanan CRT.

Berikut adalah konfigurasi ServerLayout.

Section "ServerLayout"
	Identifier	"Multihead Layout"
	Screen		0 "Default Screen" 0 0
	Screen		1 "External Screen" LeftOf "Default Screen"
	InputDevice	"Generic Keyboard"
	InputDevice	"Configured Mouse"
	InputDevice     "stylus"	"SendCoreEvents"
	InputDevice     "cursor"	"SendCoreEvents"
	InputDevice     "eraser"	"SendCoreEvents"
	InputDevice	"Synaptics Touchpad"
#	Option		"Xinerama" "true"
EndSection

Pada konfigurasi di atas, saya menon-aktifkan opsi Xinerama. Kalau opsi ini dijalankan, kita akan memiliki desktop super lebar. Kita bisa drag satu window menembus batas. Tapi kalau opsi ini dimatikan, seolah-olah ada dua desktop yang terpisah, mouse pointer bisa tembus, tapi window aplikasi tidak.

Kalau Anda menonton Swordfish, Stanley Jobson mendapatkan konfigurasi Xinerama. Ini dapat dilihat dari screensaver komet yang berjalan mengelilingi keenam screen yang tersedia. Tergantung kebutuhan, opsi ini bisa dinyalakan atau dimatikan.

Setelah selesai, logout dari desktop. Untuk memastikan, restart X server dengan kombinasi tombol Ctrl+Alt+Backspace. Kalau segalanya berjalan lancar, dual head akan tampil di hadapan kita. Perlu diperhatikan, kadang resolusi layar tidak berjalan sesuai harapan. Kadang kita perlu reboot agar resolusinya benar.

Demikian artikel kali ini, semoga bermanfaat.


Konfigurasi SVN-HTTP di OpenSuSE 10.2

Artikel ini akan menjelaskan tentang konfigurasi Apache dan OpenLDAP di OpenSuSE 10.2 agar Subversion Repository yang kita miliki bisa diakses melalui protokol HTTP.

Pertama, instal software yang dibutuhkan. Jalankan Yast dan instal paket-paket berikut:

  • subversion

  • apache2

  • subversion-server

  • yast2-http-server

Setelah itu, modifikasi executable Subversion agar repository yang dihasilkan memiliki nilai umask yang tepat. Caranya dapat dilihat di sini.

Lalu buat repository untuk percobaan, sebagai contoh saya akan membuat repository di folder /opt/repository/repo-percobaan.

<code>svnadmin create --fs-type fsfs /opt/repository/repo-percobaan</code>

Selanjutnya, kita akan mengkonfigurasi Apache agar membaca folder tersebut dan memetakannya ke URL /svn. Jadi, bila kita mengakses http://localhost/svn/repo-percobaan di browser, Apache akan menampilkan isi repository kita.

Caranya, buka Yast, kemudian masuk ke Network Services > HTTP Server. Yast Control Panel

Ikuti wizard tanpa perubahan sampai layar terakhir. Setelah itu, klik Expert Configuration.

Expert Configuration

Layar pertama adalah pilihan port yang dilayani Apache. Tambahkan port 443 untuk mengaktifkan SSL.

Port SSL

Setelah itu, masuk ke tab Server Modules. Aktifkan module dav, dav_fs.

Apache Module

Kita juga butuh modul tambahan untuk Subversion. Klik Add Module, tambahkan modul dav_svn dan authz_svn.

Add Subversion Module

Selesai dengan Yast. Klik OK untuk menyimpan perubahan. Sekarang kita akan mengedit konfigurasi modul Subversion agar membaca folder repository kita.

Buka file /etc/apache2/conf.d/subversion.conf. Di sana sudah disediakan template yang siap diedit sesuai kebutuhan. Untuk tahap pertama ini, ubah isi file tersebut menjadi seperti ini.

<code><IfModule mod_dav_svn.c>
<Location /svn>
   DAV svn
   SVNParentPath /opt/repository
</Location>

</IfModule></code>

Server ini akan digunakan untuk beberapa project sekaligus. Untuk setiap repository baru yang dibuat di kemudian hari, tidak perlu setting ulang Apache. Cukup buat folder repository baru di dalam /opt/repository.

Save file tersebut, dan restart Apache melalui Yast. Repository sudah bisa dibaca. Arahkan browser Anda ke http://localhost/svn/repo-percobaan. Instalasi yang sukses akan menghasilkan tampilan seperti ini.

Browse Repository Content

Silahkan baca artikel ini untuk mengaktifkan otentikasi melalui OpenLDAP.


MP3 di Linux

Distro Linux yang gratis umumnya tidak menyertakan dukungan MP3, Flash, DVD, dan berbagai format file non-open-source yang lainnya. Ini disebabkan karena format tersebut dilarang di beberapa negara, walaupun di Indonesia diperbolehkan. Ini merupakan masalah yang sudah banyak jawabannya. Bahkan beberapa distro populer sudah memudahkan cara instalasinya.

Mari kita lihat dua distro populer, Ubuntu dan OpenSuSE. Pada Ubuntu Feisty, ada paket yang khusus untuk mengatasi masalah ini, namanya ubuntu-restricted-extras. Cukup buka command prompt, dan ketikkan

sudo apt-get install ubuntu-restricted-extras

Paket ini ada di repository multiverse, jadi pastikan komputer Anda memiliki database dari repository tersebut.

Paket ubuntu-restricted-extras ini memungkinkan kita untuk:

  • Memainkan MP3

  • Memainkan DVD

  • Membuka website ber-Flash

  • Membuka website ber-Java Applet

  • Menggunakan font Arial, Trebuchet, dan font Windows lainnya

Untuk OpenSuSE 10.2, kita harus tambahkan repository packman. Buka Yast, klik Installation Source. Nanti kita akan disuguhi berbagai pilihan protokol. Pilih protokol HTTP.

Selanjutnya, kita akan ditanyai dua hal, nama server repository, dan folder tempat database paket berada. Masukkan ftp.uni-erlangen.de pada kolom nama server, dan /pub/mirrors/packman/suse/10.2 pada nama folder.

Tidak, saya tidak salah ketik, protokolnya memang HTTP dan alamat servernya diawali dengan FTP. Kalau tidak percaya coba saja sendiri, atau lihat di sini.

Setelah repository ditambah, Yast akan mendownload database aplikasi yang disediakan, untuk kemudian mengupdate database internalnya. Bila koneksi internet Anda lambat, bersabar sedikit.

Begitu repository selesai ditambah, kita bisa buka menu Software Management, dan Search dengan keyword libxine1. Ini adalah library yang dibutuhkan agar Amarok bisa memainkan MP3. Amarok adalah aplikasi pemain musik (music player) di KDE.

Instal libxine1, dan Amarok akan segera bisa menyanyikan MP3.

Selamat mencoba.


NTFS Write di OpenSuSE 10.2

Di Ubuntu, menulis ke partisi NTFS sangat mudah. Cukup lakukan

sudo apt-get install ntfs-config

dan partisi NTFS siap ditulisi.

Di OpenSuSE 10.2, tidak semudah ini. Secara default, repository OpenSuSE tidak mengandung ntfs-3g, paket yang dibutuhkan untuk menulis ke NTFS, yang siap digunakan. Oleh karena itu, beberapa orang memilih untuk mengkompilasi sendiri, salah satunya Oom Andi Sugandi.

Tetapi akhirnya saya menemukan cara yang mudah, tidak melibatkan kompilasi ulang. Berikut caranya.

Tambah Repository

Pertama, kita harus menggunakan repository milik Jan Engel***. Masuk ke Yast, dan pilih Installation Source. Kita akan menggunakan protokol FTP. Alamat servernya adalah ftp-1.gwdg.de dan folder repositorynya adalah /pub/linux/misc/suser-jengelh/SUSE-10.2/. Silahkan tambahkan entri tersebut dan klik OK. Yast akan segera memperbaharui database aplikasinya.

Instalasi Paket

Selanjutnya, kita bisa langsung menginstal paketnya. Dari Yast, buka Software Management, dan cari dengan keyword ntfs. Kita akan menemukan paket ntfs-3g. Instal paket tersebut. Yast akan meminta paket tambahan, yaitu fuse. Instal saja dua-duanya.

Edit fstab

Sebelum mengubah isi /etc/fstab, jangan lupa untuk melakukan umount pada partisi windows yang kita miliki. Agar partisi windows kita dimount secara otomatis pada saat boot, kita perlu mengedit file /etc/fstab. Temukan entri seperti ini,

/dev/sda1            /media/windows/C     ntfs    ro,users,gid=users,umask=0002,nls=utf8 0 0

dan ubah menjadi seperti ini

/dev/sda1            /media/windows/C     ntfs-3g    silent,unmask=0,locale=en_US.utf8 0 0

Setelah itu, kita bisa menguji coba dengan perintah mount -a. Di komputer saya muncul warning sebagai berikut.

WARNING: Deficient Linux kernel detected. Some driver features are
         not available (swap file on NTFS, boot from NTFS by LILO), and
         unmount is not safe unless it's made sure the ntfs-3g process
         naturally terminates after calling 'umount'. If you wish this
         message to disappear then you should upgrade to at least kernel
         version 2.6.20, or request help from your distribution to fix
         the kernel problem. The below web page has more information:
         http://ntfs-3g.org/support.html#fuse26

Tapi warning ini tidak berbahaya.

Edit Boot Config

Selain fstab, ada satu file lagi yang harus diedit agar mounting otomatis berjalan lancar pada saat booting. Edit file /etc/sysconfig/kernel. Cari baris berikut

MODULES_LOADED_ON_BOOT=""

dan ganti menjadi seperti ini

MODULES_LOADED_ON_BOOT="fuse"

Partisi NTFS siap digunakan. Selamat mencoba.