Windows, Apache, mod_python な環境で virtualenv 上の django を動かしてみた
環境構築に使ったリポジトリはここ
https://bitbucket.org/toruuetani/virtualenv-modpython-test
基本的にはここのまま。
http://mydjangoblog.com/2009/03/30/django-mod_python-and-virtualenv/
なぜ必要か
Pythonはsite-packages以下にすべてのライブラリをインストールするため、プロジェクト毎に使うライブラリが異なる場合に困ったことになる。それを解決するのが virtualenv で、サンドボックスを作成できる。
なので最近は virtualenv で環境を構築して、そこに必要なライブラリをインストールして使うようにしている。Django でアプリを作る場合も当然 virtualenv 上で作るわけなんだけども、最終的には Apache で動かすことになる。そこで virtualenv 環境のライブラリを Apache, mod_python から使えるか実験してみた。※ 過去のプロジェクトを動かしたかったので、python2.5&mod_pythonを使っている。
構築手順
D:/Work/venv_test を作業ディレクトリとする。Python、Apache、mod_pythonをダウンロードしておく。
1. python 2.5をインストール
2. virtualenv.py を D:/Work/venv_test にコピー
3. C:\python25\python.exe virtualenv.py . --no-site-package
4. Apache を D:/Work/venv_test/apache にインストール
5. D:/Work/venv_test/Scripts/activate.bat を実行
6. easy_install -UZ django
7. easy_install -UZ mod_python-3.3.1.win32-py2.5-Apache2.0.exe
8. 以下の内容でmypython.pyを保存
activate_this = 'D:/Work/venv_test/Scripts/activate_this.py' execfile(activate_this, dict(__file__=activate_this)) from django.core.handlers.modpython import handler
9. D:/Work/venv_test/apache/conf/httpd.conf に以下の設定を追記
Alias /static "D:\Work\venv_test\djtest\static" LoadModule python_module "D:\Work\venv_test\Lib\site-packages\mod_python-3.3.1-py2.5-win32.egg\mod_python_so.pyd" <VirtualHost 127.0.0.1:80> <Location "/"> SetHandler python-program PythonPath "['D:\Work\venv_test\Lib\site-packages', 'D:\Work\venv_test'] + sys.path" PythonHandler mypython SetEnv DJANGO_SETTINGS_MODULE djtest.settings </Location> <Location "/static"> SetHandler None </Location> </VirtualHost>
Windows7のVHD bootとDisk2vhdで快適環境構築=>挫折した・・・
Windows7になってかなり快適になったけども、使い続けるといろいろ問題が出てくることが多い。特にVisual Studioとか開発環境を複数入れたり、再インストールしたりするとよく問題が起こる。つい最近もVisual Studio 2008にWindows Mobile 6.5.3の開発環境を構築したら、デザイナ画面を開くと必ずVisual Studioが落ちるようになって、どうしようもなくなった。それでVisual Studioをアンインストールするしたりいろいろやってたら、Windows Mobile デバイスを全く認識しなくなってOSの再インストールしか打つ手がなくなってしまった。とりあえずデータは別パーティションにあるからそれほど手間ではないとは言え、OSのインストール時間がもったいない。これを機にもう少し簡単にする手順を考えてみる。ちなみにこれを書いてる時点では理論だけで実行してない。休み明けに試す予定。=>試した結果全然快適じゃなかった・・・
現在の構成
- Windows 7 Ultimate
- 物理的なHDDは1つでパーティションを2つに分割
- 1つはOSをインストール
- もう1つにはデータを格納
目標とする構成
- Windows 7 Ultimate
- 物理的なHDDは1つでパーティションを2つに分割
- システムドライブをDisk2vhdでVHDファイルに変換して、データドライブに格納
- 作成したVHDファイルのサイズを拡大する。
- 普段は上記データドライブに格納したVHDをVHD bootで起動する。
- VHD bootで起動しているWindowsがおかしくなったら、既存のVHDを削除してVHDを再作成
システムドライブに最低限必要なツールだけ入れておけば、環境構築は劇的に楽になるはず。このときVisual Studioとかみたいにレジストリをいじったりするものは入れない方が良さげ。
2011/10/03 追記
- 挫折した理由その1・・・Disk2vhdがHDDのパーティション構成をそのままコピーする
- 挫折した理由その2・・・VHD Resizerが遅すぎる
時間と手間がかかりすぎて、普通にインストールしたほうがまだマシな感じだったので諦めた。
Windows7標準のバックアップと復元を使ったほうがマシかもしれない。
GUIテストフレームワークwhiteがすごい
たとえばこんなWindowsアプリがあったとして、
namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { this.textBox1.Text = "Hello white"; } } }
こんなコードでbutton1のクリック結果をNUnitでテスト可能。
using System; using NUnit.Framework; using White.Core; using White.Core.UIItems; namespace WindowsFormsApplication1Test { [TestFixture] public class Class1 { [Test] public void Test() { var exe = @"D:\Work\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug\WindowsFormsApplication1.exe"; using (var app = White.Core.Application.Launch(exe)) { var win = app.GetWindow("Form1"); var button = win.Get<Button>("button1"); button.Click(); Assert.AreEqual("Hello white", win.Get<TextBox>("textBox1").Text); } } } }
さすがにDataGridとかはテストできなそうだけど、これは調査しないとダメだな。WindowsFormsだけじゃなくて、WPFとかSilverlightもテストできるっぽいし。
ちなみに上記のコードをコンパイルするためには、テストアセンブリにWhite.Core.dllの参照が必要。
subpathsを使ったリポジトリをcloneする方法
subrepoを使わない場合とか、subrepoを使ってもsubpathsを使ってない場合なら、リポジトリは普通にcloneできる。ただしsubrepoかつsubpathsを使っていると、普通にcloneすると失敗する。
何故かというと、subpathsはhgrcにsubrepoが参照するリポジトリのパスを格納しているから。
cloneしてもhgrcは作成されず、hgrcは自分で作成しないといけない。
なのでhgrcにsubpathsを格納しつつpullすれば、cloneと同じような効果が得られる。
ただし毎回手打ちでやるのも面倒なので、バッチファイルを用意してみた。2段階までネストに対応。
各リポジトリ(トップ、ネスト1段階目、ネスト2段階目)のパスと、ネストしたリポジトリを格納するディレクトリを変更すれば使えるはず。ディレクトリ構成はこんな感じ.
PATH_TO_TOP ├─.hg ├─SECOND_DIR ├─.hg ├─THIRD_DIR ├─.hg
@ECHO OFF SET ROOT_DIR=%~DP0 SET TOP_REPO=PATH_TO_TOP SET SECOND_REPO=PATH_TO_SECOND SET THIRD_REPO=PATH_TO_THIRD SET TOP_HGRC=%ROOT_DIR%\.hg\hgrc SET SECOND_HGRC=%ROOT_DIR%\SECOND_DIR\.hg\hgrc :CREATE_TOP hg init ECHO [paths]>%TOP_HGRC% ECHO default = %TOP_REPO%>>%TOP_HGRC% ECHO;>>%TOP_HGRC% ECHO [subpaths]>>%TOP_HGRC% ECHO subrepo_second = %SECOND_REPO%>>%TOP_HGRC% :CREATE_SECOND IF NOT EXIST %ROOT_DIR%SECOND_DIR MKDIR %ROOT_DIR%SECOND_DIR CD /D %ROOT_DIR%SECOND_DIR hg init ECHO [paths]>%SECOND_HGRC% ECHO default = %SECOND_REPO%>>%SECOND_HGRC% ECHO;>>%SECOND_HGRC% ECHO [subpaths]>>%SECOND_HGRC% ECHO subrepo_third = %THIRD_REPO%>>%SECOND_HGRC% :UPDATE CD /D %ROOT_DIR% hg pull hg update -C :END PAUSE
subrepoをさらに便利に使うためにはsubpathsを使おう
これの続き。
subrepoは確かに便利なんだけども、あるシチュエーションでは使いにくいことになる。
- サーバの名前が変更されたとき
- 場所によってpushする先が違うとき(滅多にないだろうけど)
例えば、あるマシンAではsubrepo Aにpushしたりpullしたいが、あるマシンBではsubrepo Bにpushしたりpullしたい、だけど履歴は共有したい、なおかつマシンBからsubrepo Aはアクセス出来ない場合(マシンAを中心に履歴は共有する)。あるのか?というぐらい限定的だけども、現在自分が困っていて、その解決策っぽいのが見つかったのでメモ。
解決先はこれ -> http://mercurial.selenic.com/wiki/SubrepoRemappingPlan
前回 .hgsub にリポジトリのURLを記述していたが、今回はリポジトリのエイリアスを記述する。
echo subdir = subrepo_name > .hgsub
.hgsubはこうなる。
subdir = subrepo_name
次にメインリポジトリの.hg/hgrcに[subpaths]を記述する。
[subpaths] subrepo_name = https://bitbucket.org/toruuetani/virtualenv-scaffold
subdirとsubrepo_nameはかぶらないようにすること。同名だとsubrepoがネストしてたりすると余計な置換が働いて、正しいURLにならないことがある?
subrepoを試してみた
前から気になってた、Mercurialのsubrepoの使い方がなんとなくわかったのでメモ。
何がうれしいのか
別管理のリポジトリを一緒に扱える。具体的には、共通ライブラリは別のリポジトリで管理しつつ、それを利用するアプリのリポジトリの下に共通ライブラリのリポジトリを配置できる。Subversionで言うところのベンダーブランチとかsvn:externals。
ベンダーブランチ/svn:externalsよりもうれしいのは、アプリ側のリポジトリからライブラリ側のリポジトリのリビジョンが指定できること。アプリ側のリポジトリを特定のリビジョンに更新したら、ライブラリ側のリポジトリもその時指定していたリビジョンに更新される。これはかなり便利。
作り方
まずはアプリ側のリポジトリ生成。これは普通に作る。
hg init
次にディレクトリを作って、ライブラリのリポジトリを作る。新規リポジトリをつくってもいいが、それだとあまり意味が無いので、既存のリポジトリをcloneする。
mkdir subdir cd subdir hg clone https://bitbucket.org/toruuetani/virtualenv-scaffold .
最後にsubrepo設定。
cd.. echo subdir = https://bitbucket.org/toruuetani/virtualenv-scaffold > .hgsub
.hgsubの中身はこんな感じで、配置先ディレクトリ = ターゲットのリポジトリパス(ディレクトリでもURLでも可)とする。
subdir = https://bitbucket.org/toruuetani/virtualenv-scaffold
そうするとsubdirが管理下に入るのでコミットする。
コミットすると.hgsubstateがリポジトリに追加される。このファイルに、ライブラリ側のリビジョンが記録される。
この状態だとライブラリ側のリポジトリはdefaultブランチの最新なので、好きなリビジョンに更新する。
cd subdir
hg up c59d68bcc05c
そうすると.hgsubstateもそのリビジョンを指すようになるのでコミット。
こうしてできたアプリ側のリポジトリをcloneして、最新のリビジョンにupdateするとライブラリ側のリビジョンも[c59d68bcc05c]まで更新される。
もちろんライブラリ側のリポジトリは普通のリポジトリでもあるので、変更したらclone元にpushもできる。まだ使い始めたばかりだが、これはかなり便利な気がする。