Thursday, January 8, 2009

Web uygulamasını deploy ederken python yardımı

Yazdığım bir web uygulamasının dosyalarını web sunucusuna ftp ile göndermeye çalışırken çektiğim eziyet yüzünden aşağıdaki özellikleri içeren bir script yazmaya karar verdim.
    Script;
  1. Benim seçeceğim bir klasör altındaki tüm dosyaları tarayacak.

  2. Benim belirteceğim süre içerisinde güncellenmiş dosyaları bulacak.

  3. Bulduğu dosyalar CVS (.cvs) ya da SVN (.svn) tarafından kullanılan dosyalar olmayacak

  4. Seçilen dosyaları belirteceğim bir sunucunun belirteceğim bir klasörüne secure ftp ile kopyalacak.

Python standart library içerisisinda ftp istemcisi için ftplib modülü bulunuyor. Fakat bu modül güvenli bağlantıyı (SSH2) desteklemiyor. Bu devirde de ssh haricinde bağlantı kabul eden hosting firması yoktur diye tahmin ediyorum. Google'a arama yaparken Paramiko adındaki modülü buldum. Eğer easy_install kurulu ise paramiko'yu kurmak çok kolay. Burada paramiko kurulumundan bahsetmeye gerek yok zaten README dosyasında detaylı bir şekilde anlatmış adam. Bir hayırsever de paramiko modulünü almış ve üzerine basitleştirilmiş, http://media.commandline.org.uk/code/ssh.txt adresinden indirebileceğiniz python kodunu yazmış. Ben de bu kadar hazır yazılmış kodun üzerine asağıdaki satırları yazdım.

import subprocess
import sys
from ssh import Connection

if len(sys.argv)<4:
print 'usage : python ' + sys.argv[0] + ' source_dir destination_dir hour(s)'
sys.exit()

source_dir = sys.argv[1]
destination_dir = sys.argv[2]
minutes = 60 * int(sys.argv[3])

findCommand = 'find ' + source_dir + ' -type f -mmin -' + str(minutes)
process1 = subprocess.Popen(findCommand.split(), stdout=subprocess.PIPE)
process2 = subprocess.Popen('grep -v .svn'.split(), stdin=process1.stdout, stdout=subprocess.PIPE)

files = process2.stdout.read().strip().split('\n')
host = 'HOST'
username = 'USER'
password = 'PASSWORD'
print 'connecting to ', host
ftp = Connection(host, username=username, password=password)
print 'connected.'
for file in files:
local = file
remote = destination_dir + file.split(source_dir)[1]
print 'sending file ', local, ' to ', remote
ftp.put(local, remote)
ftp.close()
print 'connection closed.'

Yeni güncellenmiş dosyaları bulup bunlar arasından SVN(subversion) dosyaları ayıklamak için linux find ve grep komutlarından yararlandım. Örneğin:
find . -type f -mmin -60 |grep -v 'svn'

komutu bulunduğun dizindeki dosyalardan (klasörler hariç) son 60 dakika içinde güncellenenleri bulur. (subversion dosyalari hariç)
Python ile sistem komutlarını çalıştırmak için subprocess modülünü kullandım. Subprocess modülü ile
  • Sistem komutları çalıştırılabilir.
  • Bir process'in çıktısı başka bir process'e girdi olarak yönlendirilebilir(pipe)
  • Çalıştırılan process'in çıktısı python script'i içinden okunabilir.

Yukarıdaki script'te find komutu çıktısı subprocess modulu yardımı ile grep komutuna veriliyor ve sonuç grep process'inin stdout alanından okunuyor. Yukarıdaki script'i ftp.py olarak kaydettim. /home/ilkinulas/projects/webapps/test dizini altındaki son 5 saat içinde güncellenmiş dosyaları ftp ile web sunucusundaki /home/ilkinulas/webapps/ dizinine atmak için aşağıdaki komutu yazmak yeterli oluyor.
python ftp.py /home/ilkinulas/projects/webapps/test /home/ilkinulas/webapps 5

1 comments:

Gökmen Görgen said...

Şu subprocess.Popen işlevi için bundan daha güzel bir örnek kod olamazdı. Paylaşım için teşekkürler =).