3 Temmuz 2010 Cumartesi

Subversion (SVN) Servislerinin HTTPS Üzerinden Sunulması

 Subversion (SVN) servisleri aşağıdaki değişik yöntemlerle verilebilmektedir:
  • Dosya sistemi üzerinden
  • SVN protokolü ile
  • SSH tüneli kullanarak
  • HTTP/HTTPS protokolü üzerinden DAV ek özelliklerini (extensions) kullanmak suretiyle
Yazılım geliştiriciler, versiyon kontrol sunucusu kullanıyorlarsa çoğunlukla bu sunucular üzerindeki ambarlara (repositories) kendi geliştirme ortamlarından (yani uzaktan) erişmek durumundadırlar. Bu durumda her nekadar dosya sistemi üzerinden erişimin de gerektiği durumlar olmasına rağmen genel olarak dosya sistemi üzerinden erişmeleri söz konusu değildir. Dolayısıyla uzaktan erişimi sağlamak üzere SVN sunucularının vermiş oldukları SVN protokolünü kullanmak düşünülebilir. Güvenli yerel alan ağları bulunan yerlerde yeterli görülebilecek olan bu metod, güvensiz ağ ortamlarında veya uzak ağlardan erişim gerektiği durumlarda yetersiz olmaktadır. Bu durumda da SSH tünelleri üzerinden açık anahtar şifreleme metodları kullanarak hem oturum açılışının hem de transfer edilen verinin güvenliği sağlanmış olacaktır. SVN kullanılan projelerde oldukça popüler olan bu metod, geliştiricilerin bilgisayarlarında SVN istemcisine bütünleşik veya ayrı çalışan bir SSH istemcisi gerektirmektedir. İstemci tarafında bu gereksinimi ortadan kaldırmak için HTTP protokolünün seçilmesi, bunu güvenli hale getirmek için de HTTPS kullanılması iyi bir tercih olacaktır. Bu yazımda da HTTPS protokolü üzerinde DAV ek özelliklerini kullanarak nasıl SVN servisi sunulabileceği anlatmaya çalıştım. Anlatılanlar aşağıdaki yazılımlar kurulu olan bir sistem üzerinde doğrudan uygulanabilir:
  • Debian linux dağıtımı
  • Apache 2.x Web sunucusu
Apache sunucusuna dav ve authz_svn modüllerinin yüklenmesi için debian'ın apt-get aracını kullanıyoruz:
apt-get install libapache2-mod-svn
Apache mods-enabled dizini içinde dav_svn.load ve authz_svn.load linklerinin yaratılmış olduğu ve aşağıdaki satırları içerdikleri görülmelidir:
LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so
LoadModule authz_svn_module /usr/lib/apache2/modules/mod_authz_svn.so
Aynı dizin içindeki dav_svn.conf dosyası SVN servisi ile ilgili ayarları içermek üzere kullanılabilir. Ancak burada söz konusu ayarların aşağıdaki gibi apache'nin HTTPS protokolü üzerinden çalışan virtual host ayar dosyasına konulması tercih edildi:
...
<Location /svn/repo1>
  DAV                svn
  SVNPath            /svn/repo1
  AuthzSVNAccessFile /svn/repo1/conf/authz

  # only authenticated users may access the repository
  Require valid-user

  # how to authenticate a user
  AuthType Basic
  AuthName "repo1 - svn ambari"

  # Dosya tabali kullanici yonetimi:
  AuthUserFile /svn/secret/.htpasswd
</Location>
...
Yukarıdaki ayarlama aşağıdaki kuralları vermektedir:
  • SVN ambarına erişim adresi, "https://www.foo.com/svn/repo1" gibi bir HTTPS URL adresi olacaktır.
  • Kullanıcı doğrulamasında HTTP basic authentication kullanacak ve kullanıcı/şifre ikilileri /svn/secret/.htpasswd dosyasından alınacaktır.
  • SVN erişim yetkileri için SVN ambar dizinindeki authz dosyası kullanılmaya devam edecektir.
Kullanıcı doğrulaması için LDAP servisleri de kullanılabilir. Bunun nasıl yapıldığı ile ilgili olarak LDAP ve Apache - Kullanıcı Doğrulaması Pratikleri başlıklı yazıya bakılabilir.
Linkler:

2 Temmuz 2010 Cuma

SVN Repository Yedekleme

"Subversion ile Salt Okunur Yansılama" başlıklı yazımda bir SVN ambarının salt okunur yansısının alınması konusu üzerinde durmuştum. Söz konusu yaklaşımda yansının olduğu sunucu, "svnsync" aracını kullanarak kısa aralıklarla ana ambarın olduğu makinaya bağlanıp kendisini senkronize etmekteydi.
Bu metodun avantajları aşağıdaki gibi sıralanabilmekteydi:
  • Uzak makinalar arasında yapılan senkronizasyon işleminde düşük bant genişliği yeterli olmaktadır.
  • Sık yedek alınabilmesi sayesinde yansı, oldukça güncel tutulabilmektedir. Senkronizasyon sıklığı dakikalara indirilebilir.
  • Çok sayıda yansı performans kaybı yaratmaksızın ana ambara bağlanabilmektedir.
Bu metodun dezavantajı ise sadece ambar içeriğinin senkronize edilebilmesi ve repository'nin ayar dosyalarının yansı ambarına taşınamıyor olması idi.
Eğer SVN ambarının bulunduğu makinada yedek almamız söz konusu ve güncellik gereksinimi çok sık değilse yukarıdaki türde bir yansılama yapmak yerine birazdan anlatacağım yöntem ile yedek alınması daha uygun olacaktır. Bu yöntem ayrıca ayar dosyalarını da içerecek şekilde ambar'ın bire bir kopyasını alacaktır. "svnadmin hotcopy" aracını kullanacağımız bu metod, "svnsync" aracını kullandığımız yöntemde de olduğu gibi SVN sunucusu hizmet verirken yedek alabilmektedir.
Yedekleme sürecinin alt adımlarını aşağıdaki gibi kabaca oluşturuyoruz:
  • Önce zamanlanmış crontab görevi çalışıyor
    • Crontab görevi, belirlenen SVN ambar dizinleri için ayrı bir script çalıştırıyor
      • Bir SVN ambarı için geçici bir dizin oluşturuluyor
      • svnadmin hotcopy aracı ile geçici dizinde kopya ambar oluşturuluyor
      • Kopya ambar paketlenerek arşivleniyor
      • Gereğinden eski arşivler silinerek diskte yer açılıyor
Yedekleme uygulamamızın bulunacağı dizin yapısını aşağıdaki gibi planlıyoruz:
  • /yedek/svn (Buraya kullanacağımız scriptleri koyacağız)
    • /yedek/svn/source (Yedeklenecek ambarlara soft linkler içerecek dizindir. Yedeklenmesini istediğimiz ambara bu dizinden soft link atarak kolayca yedekleme sürecine sokabileceğiz. Silinen linkler için ise artık yedekleme yapılmıyor olacak.)
    • /yedek/svn/target (Yedek arşivlerini içerecek)
Bu şekilde planlamamızı yaptıktan sonra şimdi uygulama kısmına geldik. Bir tek ambar için yedekleme işlemini gerçekleştirecek olan perl scripti (backup.pl) :
#!/usr/bin/perl

use Time::localtime;

$BACKUP_TTL = 10;    # Geriye donuk olarak tutulmasi istenen dosya sayisi
$TEMP_DIR   = ".tmp";

if (!defined($ARGV[0]) || !defined($ARGV[1])) {
  print "\nUsage:\ncd  && svn-hotcopy.pl <repos_home> <repo_name>\n\n";
  exit;
}

$now = time();

$current_path = `pwd`;
chomp($current_path);

$repos_home = $ARGV[0];
$repo_name  = $ARGV[1];
$repo_path  = "$repos_home/$repo_name";
$temp_path  = "$current_path/$TEMP_DIR";

# --- su anki zamanin alinisi :
$cmd   = 'date -d "'.ctime($now).'" +%Y%m%d-%H%M%S';
$timestamp = `$cmd`;

# --- veya tamamen sistem tabanli cozum:
# $timestamp = `date +%Y%m%d-%H%M%S`;

chomp($timestamp);
$backup_file_prefix = "svn.$repo_name";
$backup_filename    = "$backup_file_prefix.$timestamp.tgz";

# --- gecici dizin olusturulmasi :

$cmd = "rm -rf $temp_path";
print("$cmd\n");
system($cmd);

$cmd = "mkdir -p $temp_path";
print("$cmd\n");
system($cmd);

# --- svn hotcopy :

$cmd = "svnadmin hotcopy $repo_path $temp_path/$repo_name";
print "$cmd\n";
system($cmd);

# --- paketleme islemleri :

$cmd = "tar zcfp $backup_filename -C $temp_path $repo_name";
print "$cmd\n";
system($cmd);
 
# --- temizlik islemleri ve geriye donuk silme islemleri:

$cmd = "rm -rf $temp_path";
print "$cmd\n";
system($cmd);

print "Deleting old archives...\n";
@files = glob("$backup_file_prefix.*");

$i = 1;
for $file (reverse(@files)) {
  if ($i > $BACKUP_TTL) {
    $cmd = "rm -f $file";
    print("$cmd\n");
    system("$cmd");
  }
  $i++;
}

print "completed.\n";
Yukarıdaki perl scriptini tüm ambarlar için çalıştıracak olan shell scripti (backup.sh) :
#!/bin/bash

BACKUP_HOME=/yedek/svn
SOURCE_DIR=$BACKUP_HOME/source
TARGET_DIR=$BACKUP_HOME/target
BACKUP_SCRIPT=$BACKUP_HOME/backup.pl

for REPO_NAME in $(ls $SOURCE_DIR); do
  (cd $TARGET_DIR && $BACKUP_SCRIPT $SOURCE_DIR $REPO_NAME)
done
Yukaridaki shell sctiptini tetikleyecek crontab satırı:
0 2 * * * /yedek/svn/backup.sh  # --- each day at 02:00 AM
Hepsi bu kadar.