logo

Murat Demirten

header-nav
text

{ ubi dubium ibi libertas }

mobile-nav-trigger

Açık Kaynaklı Yazılımlara Katkıda Bulunmak

16 Kasım 2015, Pazartesi

Yazılım geliştiriciler olarak açık kaynaklı yazılım geliştirme modelinden hemen her gün faydalanıyoruz. Belirli bir özellik/fonksiyon'a ihtiyacımız olduğunda ilk işimiz açık kaynaklı bir proje yada kod parçacığı aramak oluyor. Hatta öyle ki arada sırada internet bağlantımızda sorun olduğunda neredeyse kod yazamaz hale geliyoruz veya kod yazmak içimizden gelmiyor. Peki açık kaynaklı yazılımların daha da iyi hale gelebilmesi için yeterince katkı sağlayabiliyor muyuz?

Yazılımlara katkı sunmanın tek yolu yeni bir fonksiyon eklemekten ibaret değil. İyi bir test uzmanı iseniz detaylı bir hata raporu da çok önemli bir katkı anlamına gelecektir. Dokümantasyon konusunda yetenekli iseniz aynı şekilde çok önemli katkılar sunabilirsiniz. Hala ben ne yapabilirim ki... şeklinde kendinizi sorguluyorsanız, 4 yaşındaki bir kız çocuğunun Linux kernel projesine yaptığı katkıya şuradan bakabilirsiniz: https://github.com/torvalds/linux/commit/690b0543..35f0 :)

Bu yazımızda ise konuyu daha çok C/C++ projelerine yeni bir fonksiyon ekleme senaryosu üzerinden ele alıp, gençleri heveslendirmeye ve çeşitli tavsiyelerde bulunmaya çalışacağız. Örnek bir olay üzerinden gitmeye çalışalım.

Hafta sonu bir proje üzerinde çalışırken, sıklıkla kullandığım tcpreplay uygulamasının TUN/TAP aygıtı desteği bulunmadığını farkettim. Tcpreplay, network protokolleri ile yoğun çalışanlar için daha önceden yapılmış bir capture işlemine ait paketlerin aynı şekilde veya bazı alanları değiştirilerek ağ üzerine tekrar gönderilmesini sağlamaktadır. Böylelikle belirli bir senaryo üzerinde kontrollü bir ortamda aynı trafik ile tekrar tekrar çalışma şansı bulabilirsiniz. Hatta örneğin 1 Mbps gibi düşük bir hızda alınan kaydı, 1 Gbps gibi yüksek hızlarda tekrar ettirebilir ve uygulamanızı yoğun yüklere karşı test edebilirsiniz.

Normal senaryoda tcpreplay'i başka bir makinede çalıştırıp üretilen trafiği kendi makinenizde yakalayıp işlemeniz gerekiyor, dolayısıyla 2 sisteme ihtiyaç duyuluyor. Elinizin altında ikinci bir sistem yok ise, sanal bir makine de oluşturabilirsiniz fakat bu iş için sanal makineyle uğraşma zahmetine girmeden de bir çözüm var; işletim sisteminin sağladığı TUN/TAP aygıtı desteğini kullanmak. [1]

Bir TUN/TAP aygıtı, sanki fiziksel bir ağ arayüzünden geliyormuş yada gidiyormuş gibi kullanıcı kipinden paket göndermenize imkan verir (OpenVPN gibi uygulamalarda da yoğun biçimde kullanılır). Kullanımı oldukça basittir ve bir miktar ön hazırlıktan sonra normal bir file descriptor üzerinden okuma/yazma sürecine dönüşür. Tcpreplay bu süreci desteklemediği için mecburen ayrı bir uygulama yazıp, capture dosyasından okunan paketleri uygun şekilde TAP aygıtına göndermem gerekti. Bu şekilde ayrı bir uygulama ile test yapabilir hale gelmiş oldum.

Problemi çözdükten sonra...

Tam bu noktada kendimize bir soru sormamız gerekiyor. Problemi farkettik, çözümü bulduk, tcpreplay'dan bağımsız sadece bu senaryoda çalışan küçük bir uygulama da yazdık. Şimdi neden biraz daha uğraşıp, bilgilerimiz de güncel iken bu desteği tcpreplay içerisine eklemeye çalışmıyor ve böylelikle başkalarının da kolaylıkla faydalanabileceği bir hale getirmiyoruz?

Bunu bir borcun camiaya geri ödemesi olarak da düşünebiliriz, dolayısıyla manevi bir tatmin de söz konusu olabilir. Aynı zamanda bu türden ana projeye kod gönderme süreçleri size de mutlaka az yada çok yeni bir şeyler öğretiyor olacaktır.

Capture dosyasından okuma yapıp bir TAP aygıtı üzerine paket gönderen küçük uygulamamız, parametrik olarak hedef MAC adresi değiştirme, VLAN ID düzenleme yada paketleri belirli bir hızda gönderme gibi gelişmiş özelliklere sahip değil. Oysa tcpreplay içerisinde bu özellikler gayet başarılı şekilde yapılabiliyor. Eğer problemi tcpreplay bünyesinde çözecek olursak, tüm bu diğer özelliklerden TAP aygıtları için de faydalanabiliyor olacağız.

Git & Github

Günümüzde açık kaynaklı projelerde yoğunlukla git versiyon kontrol sistemi kullanılıyor. Linus Torvalds'ın bilişim dünyasına neredeyse kernel kadar önemli katkılarından olan git, özellikle bir Rails uygulaması olan Github'ın çıkışıyla birlikte geliştiriciler arasında oldukça popüler hale geldi. Şu an Github, 30 milyon civarında repository'i bünyesinde barındırmaktadır. Eğer git tabanlı çalışma modellerine aşina değilseniz, güzel bir özete https://www.atlassian.com/git/tutorials/comparing-workflows adresinden erişebilirsiniz.

Tcpreplay projesi de Github üzerinde tutuluyor. Projede çalışmaya başlamadan önce Pull Requests bölümünü kontrol ederek, üzerinde çalışacağımız fonksiyonla ilgili halihazırda bir başkası tarafından gönderilmiş ve orjinal kod ile birleştirilmeyi bekleyen bir patch olup olmadığını kontrol etmeliyiz.

Eğer benzer bir çalışma yok ise, Issues bölümünde arama yapıp konunun daha önce gündeme gelip gelmediğini ve geldi ise ne gibi yanıtlar alınmış olduğunu; özellikle ana geliştiricilerin bu fonksiyona karşı fikirlerini öğrenmeye çalışmanız da yerinde bir davranış olacaktır.

Mevcut bir çalışma veya konuyla ilgili önemli itirazlar yok ise, değişiklikleri yapmaya başlayabiliriz. Bunun için öncelikle projeyi kendi hesabımıza fork etmeliyiz.

Feature branch ile çalışma

Projeyi kendi hesabımıza fork ettikten sonra, master branch üzerinde çalışmak yerine, geliştirilecek özellikle ilgili yeni bir branch açıp, çalışmalarımızı onun üzerinde yapmalıyız. Git tabanlı yazılım geliştirme modelinde buna feature branch ismi verilmektedir.

Genel bir yaklaşım olarak feature branch isimlerinin geliştirilecek fonksiyonu çağrıştıran anlamlı kısaltmalar olması beklenir. Farklı dilleri konuşan geliştiriciler arasında ortak bir dil kurulabilmesi amacıyla tüm isimlendirme, kod açıklamaları ve commit mesajlarının İngilizce olması gereklidir.

Çalışmaları yapacağımız feature branch'ın ismi tuntap-device-enhancement olsun. Projeyi çalışma dizinimize klonlayıp branch oluşturuyoruz:

$ git clone git@github.com:demirten/tcpreplay.git
$ git checkout -b tuntap-device-enhancement
Switched to a new branch 'tuntap-device-enhancement'

Gnu Build Sistemi Araçları

Özellikle C/C++ projeleri üzerinde çalışırken make, autoconf, automake gibi araçların kullanımı hakkında asgari düzeyde bilgi sahibi olunması gerekecektir. Tcpreplay kodunu klonladığınızda, proje ana dizininde alışageldiğiniz configure betiğinin yer almadığını göreceksiniz. Bu betiği oluşturmak için autoconf ve automake araçlarını kullanmamız gerekiyor. Bu işleri sizin için kolaylaştıracak olan ana dizindeki autogen.sh betiğini de kullanabilirsiniz. Bunun için öncelikle sisteminizde gerekli araçların yüklendiğinden emin olmalısınız:

$ sudo apt-get install make autoconf automake autogen

Ardından ./autogen.sh ile betik uygulamasını çalıştırın. Bir miktar uyarı mesajı sonrasında çalışması bittiğinde configure betiği de oluşmuş olacaktır. Şimdi artık ./configure && make && make install döngüsü ile uygulamayı derleyip sistemimize kurabilecek haldeyiz.

GNU make, autoconf & automake hakkında bilgi almak için vaktiyle hazırlamış olduğum aşağıdaki 2 dokümandan da faydalanabilirsiniz:

Uygulama üzerinde çalışırken..

Mevcut bir uygulama üzerinde değişiklik yapmak için, uygulama kodunun tümünü incelemek gerekli olmasa da genel akışı ve kullanılan soyutlamaları anlamak önemlidir. Aksi takdirde yapacağınız patch ana geliştiriciler tarafından kabul edilmeyecektir.

Yazılımcılar genel olarak egolarına düşkündür. Hazırladığınız bir patch reddedilecek olursa egonuza yenik düşmeden önce, red sebeplerini anlamaya çalışmanız daha yapıcı bir davranış olacaktır. Projelerde zaman zaman büyük anlaşmazlıklar da çıkabilir, eposta listelerinde bunun pek çok örneğine rastlayabilirsiniz. Proje ekibiyle uyum içerisinde olmanıza rağmen teknik olarak görüş ayrılıkları yaşayacak olursanız, kendi fork edilmiş repository'nizde ilgili değişiklikleri barındırmaya devam edebilirsiniz. Böylece en azından ileride sizinle benzer şekilde düşünenler için örnek bir çalışma bırakmış olursunuz.

Elbette asıl amacınız, geliştirdiğiniz yamayı ana projeye dahil ettirmek olmalıdır. Uygulamanın ana geliştiricileri sürece hakim olduklarından size farklı önerilerde de bulunabilirler. Bunları dikkate almalısınız.

Hazırladığınız yamayı FreeBSD, MacOS X gibi farklı platformlarda test edip sonuçlarını bildirenler çıkabilir. Bu gibi durumlar size ek iş çıkarabilecek olsa da, hem bir yazılım geliştirici olarak yeni meziyetler kazanmanızı hem de yaptığınız değişikliklerden daha geniş bir kesimin yararlanmasını sağlayacaktır. İlgili projeye daha önce hiç yama göndermediyseniz, geribildirimleri dikkate alıp mümkünse kısa zaman içerisinde yanıt dönmeniz proje ekibi üzerinde olumlu bir etki bırakacaktır.

Kod düzenine saygı gösterin..

Kod yazımında GNU, K&R yada başka bir stili benimsiyor olabilirsiniz. Girintiler için mutlaka 8 boşluk yada TAB tercih ediyor da olabilirsiniz. Kaynak kod dosyalarının proje içerisindeki mevcut isimlendirmelerinden tutun da fonksiyon isimlerine kadar bir çok noktada proje ekibinden farklı düşüncelere sahip de olabilirsiniz. Ancak bunları tümüyle bir kenara bırakmalı ve aynı fikirde olmasanız dahi mevcut kodun ahengini bozmayacak şekilde yazmaya kendinizi alıştırmalısınız.

Değişiklikleri tamamladıktan sonra git diff komutuyla temiz bir patch olup olmadığını tekrar kontrol etmelisiniz. Indentation bozuklukları, patch içerisinde yer almaması gereken başka dosyalardaki değişiklikler, proje için detaylı bir .gitignore dosyası olmamasından kaynaklanan ilgisiz dosyalar gibi pek çok acemice görünecek hatayı bu şekilde farkedebilirsiniz. Göndereceğiniz patch'in hazırlanmasında ne kadar özenli davranırsanız, sonrasındaki süreç o denli kolay yürüyecektir.

Patch gönderimi

Her şey tamam ise ilgili değişiklikleri açıklayıcı bir commit mesajı ile commit ettikten sonra, bu çalışma için açmış olduğunuz feature branch'e de push etmeyi unutmamalısınız. Örneğimiz için bu komut aşağıdaki gibi olacaktır:

$ git push --set-upstream origin tuntap-device-enhancement

Örneğimizdeki ilgili patch dosyasına şuradan erişebilirsiniz: https://github.com/demirten/tcpreplay/commit/737f68b..a1

Pull request oluşturma

Değişikleri kendi feature branch'imize push ettikten sonra Github üzerinden ilgili commit'inizi görüntülediğinizde, pull request oluşturmanız için yönlendirmelerle karşılaşacaksınız. Yaptığınız bir commit ile ilgili oluşturacağınız pull request, projenin ana geliştiricilerinin merge edilmeye hazır bir geliştirme olduğundan haberdar olmalarını sağlayacaktır. Github tarafından sağlanan bu ek akış, projelere katkıda bulunma süreçlerini her iki taraf için kolaylaştırmaktadır.

Örneğimiz için pull request'i ve sonrasındaki gelişmeleri şuradan inceleyebiliriz: https://github.com/appneta/tcpreplay/pull/207

Bitirirken

Zamanımız olduğu müddetçe açık yazılımlara katkıda bulunmaya çalışmamız gerekiyor. Github gibi oluşumlar sayesinde artık sürecin kendisine özgü bir sosyal medyası da mevcut. Projelere katkıda bulundukça hem yeni bilgiler öğrenme fırsatı yakalayacak hem de yeni arkadaşlıklar edineceksiniz. Tamamen farklı ilgi ve bilgi alanlarına sahip onlarca kişi ile anlaşmaya çalışarak birlikte bir sürecin parçası olmak, iletişim yeteneklerinizi geliştireceğinden günlük çalışma hayatınıza da olumlu etkileri olacaktır.

Ve son olarak Türkçe karşılıkları tam olmadığından veya oturmadığından özellikle bu yazıda biraz fazlaca kullanmak zorunda kaldığım kavramlar için kusura bakmayınız. Bu durumu belki ayrı bir yazıda irdelememiz gerekiyor.

Kaynaklar

search
Sosyal Medya