ÇOMAR ve PiSi kardeş, sanırım herkes biliyor bunu. Biri paketleri kuruyor, güncelliyor; diğeri kurulu paketlerin yapılandırma işlerini üstleniyor. Peki, ÇOMAR ve PiSi beraber nasıl çalışıyor? Paket yapıyorsanız ya da yapmak istiyorsanız, eninde sonunda "ÇOMAR betiği yaz" diyecektir birileri size, ve elbet bu soruyu soracaksınız. PiSi paketi yapmak çocuk oyuncağı olduğundan, diğer paketlerdeki ÇOMAR betiklerini alıp ufak değişikliklerle kendi PiSi paketlerinizde kullanabildiğinizden cevabını bilmemeniz ya da öğrenmemeniz muhtemelen uzunca bir süre etkilemez sizi, ama paket yapım işinizi kolaylaştırabilir de.
PiSi kaynak paketlerinde (pspec.xml), ikili paketin (.pisi uzantılı) sağladığı ÇOMAR görevlerinin ve her görevin hangi Python dosyası tarafından sağlandığının listesi bulunur:
<Package>
<Name>python</Name>
<Files>
...
</Files>
<Provides>
<COMAR script="package.py">System.Package</COMAR>
<COMAR script="packhandler.py">System.PackageHandler</COMAR>
</Provides>
</Package>
Betikler, kaynak paket ile aynı dizindeki comar/ dizininde (hiç akla gelmez, değil mi?) bulunur. System.Package, System.PackageHandler ve System.Service dışındaki görevler PiSi ile ilgili olmadığından başka bir yazının konusu, bunlar muhtemelen Sistem Ayarları ekranındaki uygulamalardan birinin ihtiyaç duyduğu altyapıyı sağlar.
System.Package görevini yerine getiren betik, paket kurulduktan sonra, kaldırılmadan önce ve kaldırıldıktan sonra çalıştırılacak metodları içerir. Betik içinde, metodlardan herhangi birinin tanımlı olması zorunlu değildir. Dosya haklarını ve sahiplerini değiştirecekseniz postInstall() metodu, paket kaldırılmadan önce ayar dosyalarında değişiklik yapacaksanız (mod_php'yi kaldırmadan önce Apache ayarlarını değiştirmek gibi) preRemove() metodu, paket kaldırıldıktan sonra artık dosyaları temizleyecekseniz postRemove() metodu kodlarınızı yazmanız gereken yer.
import re
def postInstall(fromVersion, fromRelease, toVersion, toRelease):
module_enable('PHP5')
def preRemove():
module_disable('PHP5')
def module_enable(mod):
...
def module_disable(mod):
...
System.PackageHandler'da durum biraz daha farklı. Bu betikler, betiğin çıktığı paket kurulması/kaldırılması sırasında değil, sisteme herhangi bir paket kurulduğunda ya da kaldırıldığında çalıştırılıyor. Çekirdek modülleri ve Python kütüphaneleri gibi, paket deposunda onlarcası bulunan ve hepsine birer System.Package betiği yazsanız üç aşağı beş yukarı aynı betiğin ortaya çıkacağı paketlerde, paketçinin yükünü ve kod tekrarını azaltmak için kullanılıyorlar.
Django paketini kurduğunuzda, sistemdeki her System.PackageHandler betiği çalıştırılır ve betik içindeki metodlara, pakete ait iki XML dosyası parametre olarak verilir: metadata.xml ve files.xml. Bu dosyalardan ilki, pakete ait kimlik bilgilerinin barındırır, ikincisi ise, paketten çıkan her dosyayı ve dosyalara ait özet bilgileri. ÇOMAR betikleri, files.xml dosyasında, kendilerini ilgilendiren bir dosya varsa (mesela, Python'a ait SPH betiği, ikili paket .py dosyası içeriyorsa) ya da metadata.xml'de ilgili oldukları bir veri/etiket bulunuyorsa işlem yaparlar.
Python'a ait SPH betiği aşağıda, yeni başlayanlar için ağır bir örnek ancak örnek olsun diye yazacağım basit bir betik gerçekçi olmazdı.
import piksemel
import sys
import os
pythonPath = "/usr/lib/python%d.%d" % sys.version_info[:2]
def byteCompile(filepath):
doc = piksemel.parse(filepath)
paths = []
for item in doc.tags("File"):
path = item.getTagData("Path")
if path.endswith(".py"):
paths.append("/"+path)
if paths:
os.system("/usr/bin/python %s/py_compile.py %s" % (pythonPath, " ".join(paths)))
def removeByteCompiled(filepath):
doc = piksemel.parse(filepath)
for item in doc.tags("File"):
path = item.getTagData("Path")
if path.endswith(".py"):
try:
# Remove .pyc and .pyo
os.unlink("/%sc" % path)
os.unlink("/%so" % path)
except OSError:
pass
def setupPackage(metapath, filepath):
byteCompile(filepath)
def postCleanupPackage(metapath, filepath):
removeByteCompiled(filepath)
Bu gecelik bu kadar...