2011/05/31

2011/05/05

rpmbuild - 以 Python 2.7 為例

Red Hat Enterprise Linux 的很多東西都很舊,特別是 RHEL 5 系列。
有些新的軟體更新,它不見得會跟著推出新的 rpm 檔。
除了使用 tarball 安裝方法,也可以自己包一個 rpm 檔。

環境:RHEL 5.6

安裝必備套件
yum groupinstall "Development Tools"
yum install rpmdevtools

you should NEVER build an RPM with the root user.
絕對不要使用 root 來打包 rpm!


建立一個專門打包 rpm 的使用者帳號
useradd rpm_maker

切換成該使用者
su - rpm_maker

在 rpm_maker 的家目錄下執行
rpmdev-setuptree     # 會建立 ~/rpmbuild 目錄

下載 Python2.7 原始檔,解壓縮,放置 python-2.7.spec 與原始檔
cd ~
wget  http://www.python.org/ftp/python/2.7.1/Python-2.7.1.tar.bz2
tar  jxvf Python-2.7.1.tar.bz2
cp  ~/Python-2.7.1/Misc/RPM/python-2.7.spec  ~/rpmbuild/SPECS/
mv  Python-2.7.1.tar.bz2  ~/rpmbuild/SOURCES/

補足相關套件
yum install tk-devel tcl-devel expat-devel db4-devel gdbm-devel sqlite-devel

根據指定的 spec 建立 rpm 檔
cd ~/rpmbuild/SPECS/
rpmbuild -ba python-2.7.spec

http://blog.milford.io/2012/01/building-and-installing-python-2-7-rpms-on-centos-5-7/

Reference:
01. https://fedoraproject.org/wiki/How_to_create_an_RPM_package/zh-tw
02. http://www.grenadepod.com/2009/12/26/building-python-2-6-4-rpm-for-centos-5-4/
03. http://www.ibm.com/developerworks/library/l-rpm1/
04. http://villaroad.com/2010/10/rolling-python-2-6-2-on-centos-5-3/
05. http://willsani.com/2011/03/02/centos-5-5-x86_64-install-python-2-7/
06. http://www.joywang.info/?p=112
07. http://serverfault.com/questions/11209/python-3-0-rpms-for-centos-5-rhel-5
08. http://serverfault.com/questions/162217/upgrading-python-on-rhel5
09. http://stackoverflow.com/questions/4149361/on-linux-suse-or-redhat-how-do-i-load-python-2-7

2011/05/02

mod_python 與 mod_wsgi

Reference:
01. http://docs.python.org/howto/webservers.html
02. http://www.modpython.org/python10/
03. http://code.google.com/p/modwsgi/

Django

【安裝 Django】

Ubuntu 底下安裝可以使用:sudo apt-get install python-django
Red Hat 底下安裝可以使用:yum install Django

Ubuntu 預設會把 Django 放在:/usr/local/lib/python2.*/site-packages
Red Hat 預設會把 Django 放在:/usr/lib/python2.*/site-packages

Python won't recognize Django unless it is installed in the "site-packages" directory, so instead we just create a symbolic link to the source code in our home directory.

由上文可知,其實 Django 只要放到正確的 site-packages 下,Python 就可以認到了。
比較麻煩的就是 Python 版本的差異,例如 RHEL 5 預設只有 Python 2.4。
但是 RHEL 5 底下使用 yum 安裝的所有 Python 套件,都會放到 Python 2.4 的 site-packages。
如果你執行的環境是 Python 2.6,那就很頭大了,Python 2.6 底下 import 會少一堆東西。

較好的解決方案是使用:python-virtualenv
跑題了,之後再補充。

使用 Django 原始檔來安裝(想成是 Linux 的 tarball install 吧),自由度會比較高些。

可以下載官方版本來解壓縮,或使用 Subversion 同步一份到自己的家目錄:
cd /var/www
svn co http://code.djangoproject.com/svn/django/trunk/ django_src

使用這個命令取得 Python 的 site-packages 路徑:
#注意 python、python2.4、python2.6 的差別!
python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
python2.4 -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
python2.6 -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

選擇你的 site-packages 路徑(python2.4 或 python2.6),做一個 symbolic link 到那裡:
ln -s /var/www/django_src/django   你的 site-packages 路徑/django

把 django-admin.py 加到執行路徑(PATH)裡:
sudo cp /var/www/django_src/django/bin/django-admin.py /usr/local/bin

基本上這樣就安裝好 Django 了。
可以進入你的 Python 2.* 環境,測試一下:
>> import django



【建立 Django 專案】

建立一個新的 Django 專案:
cd /var/www/
django-admin.py startproject hello_django

裡面預設的結構是:
__init__.py
manage.py
setting.py
urls.py

再增加幾個資料夾到專案裡面:
cd /var/www
ln -s /var/www/django_src/django/contrib/admin/media  admin_media

cd /var/www/hello_django
mkdir media
mkdir templates

setting.py 裡面可以設置管理資訊與資料庫設定:
ADMINS = (
     ('Your Name', 'your_email@domain.com'),
)

DATABASE_ENGINE = 'mysql'            # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'databaes_name'    # Or path to database file if using sqlite3.
DATABASE_USER = 'user_name'          # Not used with sqlite3.
DATABASE_PASSWORD = 'user_password' # Not used with sqlite3.
DATABASE_HOST = ''                 # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = ''                 # Set to empty string for default. Not used with sqlite3.

TEMPLATE_DIRS = ( 
    "/var/www/hello_django/templates/"    # Absolute path
)

MEDIA_ROOT = '/var/www/hello_django/media/'   # Absolute path to the directory that holds media.

# URL that handles the media served from MEDIA_ROOT. 
# Make sure to use a trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/" 
MEDIA_URL = 'http://yourdomain.com/media/'

# URL prefix for admin media -- CSS, JavaScript and images. 
# Make sure to use a trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/admin_media/'

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
)

同步資料庫:
django-admin.py syncdb

編輯 urls.py 檔:
# Uncomment this for admin:
 (r'^admin/', include('django.contrib.admin.urls')),



【設置 Apache】




Reference:
01. http://jeffbaier.com/articles/installing-django-on-an-ubuntu-linux-server/
02. http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/
03. https://help.ubuntu.com/community/Django
04. http://nildamului.blogspot.com/2009/03/django-1.html
05. http://nildamului.blogspot.com/2009/04/django-2.html

CGI

有時候,想要瞭解某些協定、標準,最準確也最快速的方法就是直接去讀它的 RFC 文件。
應該也不用讀太多,每條協定幾乎都有摘要(Abstract)跟它的存在目的(Purpose)。

這篇是我對 Common Gateway Interface 的筆記。
先節錄幾段 Wikipedia 與 RFC 3875 的內容:

" The Common Gateway Interface (CGI) is a standard (RFC 3875: CGI Version 1.1) that defines how web server software can delegate the generation of web pages to a text-based application. Such applications are known as CGI scripts; they can be written in any programming language, although scripting languages are often used. " - Wikipedia

" The Common Gateway Interface (CGI) is a simple interface for running external programs, software or gateways under an information server in a platform-independent manner. Currently, the supported information servers are HTTP servers. " - RFC 3875

" The Common Gateway Interface (CGI) allows an HTTP server and a CGI script to share responsibility for responding to client requests. " - RFC 3875

" The server is responsible for managing connection, data transfer, transport and network issues related to the client request, whereas the CGI script handles the application issues, such as data access and document processing. " - RFC 3875

簡單來說,「HTTP 伺服器」負責管理來自 Client 端的連線、傳輸等網路協定的相關事宜。
「HTTP 伺服器」會呼叫並執行「CGI 程式」,「CGI 程式」負責處理應用程式面的事宜,
例如,Client 端要求的檔案,是否需要經過處理,是否需要存取資料庫等等。

「CGI 程式」允許使用許多不同的程式語言來實作。
但那麼多種程式語言,「HTTP 伺服器」如果呼叫某種語言的「CGI 程式」,
就得有對應該程式語言的呼叫介面,那「HTTP 伺服器」的開發人員會瘋掉。

所以「CGI」就出現了。

「CGI」規範了「HTTP 伺服器」與「CGI 程式」間的連接。
「CGI」是包在「HTTP 伺服器」裡面的。

如果想要用某種程式語言撰寫「CGI 程式」供「HTTP 伺服器」叫用,
該程式語言必須有遵守「CGI」規範的接口。
在實際的例子中,這些接口就是 Apache 伺服器上的:
mod_php、mod_python、mod_ruby、mod_perl、mod_mono 等等。

「HTTP 伺服器」只要提供一套「CGI」規範給各種程式語言遵循即可,
而各種程式語言如何去實作「CGI」規範的接口,就是它自己的事了。

通常,Client 端送來的參數跟 URL 其實就是在呼叫要執行的「CGI 程式」了。

我畫了一張簡圖,希望大家指正:




【WSGI】

" WSGI (Web Server Gateway Interface) was created as a low-level interface between web servers and web applications or frameworks to promote common ground for portable web application development. WSGI is based on the existing CGI standard. " - Wikipedia

Python 的 WSGI,應該是欲取代掉 mod_python 的角色。
同一種程式語言,但該語言的多種框架如果對應到多種不同的「HTTP 伺服器」,還是很累人。
早先 Python 爲了迎合 CGI、FastCGI、mod_python 等不同規範,吃了不少苦頭。

但實際應用上,WSGI 沒那麼簡單。
WSGI 還可以起到 Middleware 的作用,可以看成是伺服器 response 內容的 filter。

這篇寫得很精彩:http://blog.ez2learn.com/2010/01/27/introduction-to-wsgi/



【Rack】

" Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call. " - Wikipedia

在 Ruby 方面,受 WSGI 的啓發產生了 Rack。

" Rack 的規範非常簡單:就是需要一個 Call method 吃進一個 Enviroment 參數,然後回傳一個 Array,Array 裡面包含 status,header,body。" - XDite

請參考:http://blog.xdite.net/?p=1557

Reference:
01. http://en.wikipedia.org/wiki/Common_Gateway_Interface
02. http://tools.ietf.org/html/rfc3875
03. http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface