‘Python’ タグのついている投稿

PythonのpsutilでUDPポート監視

Windows上で特定のUDPポートがオープンになっているかを確認するのにPythonのpsutilを使ってみました。psutilはWindowsでもLinuxでも同じように使えるので、移植も簡単です。

要はZabbix agentみたいなものを作りたかったのです。

netstatコマンドで同じことをしようとすると、言語ごとに表示内容が変わったりするのを自力で整形する必要があるので、一元的に管理できるのは助かります。

インストールは
easy_install psutil
だけでOKです。

psutil – A cross-platform process and system utilities module for Python – Google Project Hosting

公式サイトを見てもらえばわかるのですが、psutilは本当に強力で、CPUの使用率からメモリ、ディスクスペース、ネットワークインターフェイスの状態、プロセスの優先度設定、停止、再開など色々なことが簡単にできます。

以下はPyDHCPLibで動いているプログラムがUDP67番ポートをListenしているかを確認するコードです。

import psutil
import re
found = False
iter = psutil.process_iter()
for p in iter:
    if re.search("python", p.name) != None:
        connections = p.get_connections(kind='udp4')
        for con in connections:
            if con.local_address == ('0.0.0.0', 67):
                found = True
                print p
                break
    if (found):
        break

あと、オフライン環境のマシンにもインストールさせたいのでeggファイルを用意します。eggファイルの形式では公開されていないので、easy_installでインストールしたものをコピーしてきます。eggファイルはpython\Lib\site-packages\psutil-0.4.1-py2.7-win32.eggにあります。

pydファイルも含まれているので、ファイルひとつだけコピーしてきて、

easy_install psutil-0.4.1-py2.7-win32.egg

でインストールできます。


httpでアクセスできるMercurialサーバを作る

サーバはCentOS 5.8です。Mercurialは2.2.2を使います。

まずは下準備で、Mercurialをインストールします。yum install mercurialでインストールできるバージョンは古いので、easy_installを使います。

# yum install gcc python python-devel python-setuptools
# easy_install mercurial

PythonとMercurialがインストールされているか確認します。以下のコマンドで何もエラーがでなければOKです。

# python
>>> import mercurial
>>> [Crtl+D]

Mercurialのリポジトリからhgweb.cgiを探します。自分の環境ではMercurialをeasy_installでインストールしたのでhgweb.cgiが入っていませんでした。

なので、リポジトリから落としてきます。

http://selenic.com/hg/file/85a358df5bbb/hgweb.cgi

以前は複数のリポジトリを公開するためには、hgwebdir.cgiというファイルを使うことになっていましたが、統合されたようで、hgweb.cgiでどちらもできるようになっています。

下記の日本語訳のページは、情報が古いので注意してください。

JapaneseCGI_Install – Mercurial

英語ページを参照するのが正しいです。

PublishingRepositories – Mercurial

Apache用にwwwユーザを作ってあるので、/home/www/hgweb.cgiに設置しました。hgweb.cgiを開いて、configの行を変更します。

config = "/home/www/hgweb.config"

hgweb.cgiには実行権限を付けておきます。

# chmod u+x /home/www/hgweb.cgi

同じディレクトリにhgweb.configを作成します。

[web]
encoding = UTF-8

[paths]
test = /var/lib/hg/test

リポジトリのパスは/var/lib/hg以下に設置することにしました。ドキュメントでは/home/user/hgの下に置くことになっています。

# mkdir /var/lib/hg
# chown www:www /var/lib/hg
# su www
$ cd /var/lib/hg
$ mkdir test
$ cd ./test
$ hg init

wwwユーザがhgを使えるようにしておきます。/home/www/に.hgrcを作成してユーザ情報を書き込みます。

$ vi ~/.hgrc
[ui]
username = webadmin <webadmin@sample.com>

で、/var/lib/hg/testに適当にファイルを作ってコミットします。コミットがひとつもないと、Webからアクセスできません。

$ touch index.html
$ hg add index.html
$ hg commit -m "first commit"

次にApacheの設定です。ScriptAliasをVirtualHostの中にでも書いておきます。

ScriptAlias /hg "/home/www/hgweb.cgi"

ここまでできたら、Apacheを再起動します。

# apachectl restart

これで、http://repository.sample.com/hg/testのようにアクセスできます。ブラウザでも、hg cloneコマンドでも可能です。

リポジトリを追加するときは、/var/lib/hg以下にディレクトリを新規作成して、そのディレクトリでhg initを実行、/home/www/hgweb.configに追記の手順です。

次に認証を追加します。Apacheの設定ファイルの、先ほどのScriptAliasの下にLocationディレクティブを追加します。

<Location /hg>
    AuthType Basic
    AuthName "Mercurial repositories"
    AuthUserFile /home/www/hg/hgusers
    AuthGroupFile /home/www/hg/hggroups
    Require valid-user
</Location>

ユーザとグループで管理できるようにしました。(グループ作りましたけど意味はなかったです)

# su www
$ mkdir ~/hg
$ cd ~/hg
$ htpasswd -c ./hgusers user1

同じ場所にhggroupsファイルも作成してグループを定義します。svnのdavのようにここでリポジトリのアクセス権限を設定したりすることはできません。

testgroup:user1

グループの書き方はこちらを参照のこと。

ユーザー認証によるアクセス制限(ベーシック認証編)(2/2)

webからのpushができるようにします。/home/www/.hgrcにセクションを追加します。

[web]
allow_push = *

この設定は各リポジトリの.hg/hgrcに書いても大丈夫のようです。そうすれば、レポジトリごとに制御できます。

問題はグループごとにアクセスできるリポジトリを制御することなのですが、これは簡単にはできないようです。

ユーザごとには読み込み制御が可能です。allow_readを使います。

この場合は、/var/lib/hg/test/.hg/hgrc(なければ作成)にwebセクションを書きます。

[web]
allow_read = user1

これで大丈夫です。トップページのリストにも、allow_readに含まれていないユーザはリポジトリが表示されません。allow_readは書かなければallow_read=*としたことと同じになります。他にもdeny_readが使えます。

参考

configuration – Mercurial set per user rights – Server Fault

それと、httpsを使わない場合はpush_ssl = falseをhgweb.configのwebセクションに書いておく必要があります。httpsでアクセスさせる場合はそのままでOKです。


Windows 7 x64にMercurialからgitを操作できるhg-gitをインストールする

Windows 7 x64にhg-gitをeasy_installから入れようとして、ハマったことのメモです。

hg-gitについてはこちら。
Hg-Git Mercurial Plugin

コマンドプロンプトから
C:\> C:\Python27\Scripts\easy_install.exe hg-git
C:\> C:\Python27\Scripts\easy_install.exe -Z hg-git
でインストールできます。(-Zオプションを付けないと、hg_git-0.3.2-py2.7.eggに圧縮されてしまうので、あとでmercurial.iniにパスを指定できなくなる)

error: Setup script exited with error: Unable to find vcvarsall.bat

まずはvcvarsall.batが見つからないと怒られます。これはVisual C++ 2008 Express Edition with SP1をインストールすればOKです。2010は使えないようなので、2008をインストールします。
Visual Studio 2008 Express | Microsoft Visual Studio
ダウンロードリストからC++を選んでダウンロードしてください。

C:\Python27>Scripts\easy_install.exe hg-git
Searching for hg-git
Best match: hg-git 0.3.2
Processing hg_git-0.3.2-py2.7.egg
hg-git 0.3.2 is already the active version in easy-install.pth

中略

  File "C:\Python27\lib\distutils\msvc9compiler.py", line 299, in query_vcvarsall
    raise ValueError(str(list(result.keys())))
ValueError: [u'path']

で、次はValueError: [u’path’]のエラーが出たので、調べると、PythonのIssueに上がっている問題のようです。パッチが出ていますが、未だに取り込まれていない様子。

Issue 7511: msvc9compiler.py: ValueError when trying to compile with VC Express – Python tracker

ここから、vcvars4.diff(最新のdiff)をダウンロードします。

パッチを充てたいので、Windowsで動くpatchを探すと、

UnxUtils | Free software downloads at SourceForge.net

ここからダウンロードできるようです。

が、なぜかpatch.exeが管理者権限を要求するので、ちょっと怖いので結局手作業でmsvc9compiler.pyをdiffに従って編集しました。まぁ、大した量ではないので…



2012/04/18追記:

コメント欄で原因と対策を教えていただきました。Windowsがpatch.exeというファイル名を勝手にブロックするようです。patchという文字列が入っていて、実行可能形式の拡張子(exeとかscrとか)だと発動するようなので、p.exeなどにファイル名を変更すれば大丈夫です。

パッチを当てられないWindows VISTA

ちなみに、install.exeやsetup.exe、update.exeなども同じ原因で権限を要求されます。

MSDNでの公式情報はこちら。

New UAC Technologies for Windows Vista

で、再度実行すると、また新しいエラーが出ました。

Reading http://launchpad.net/dulwich
Best match: dulwich 0.8.3
Downloading http://samba.org/~jelmer/dulwich/dulwich-0.8.3.tar.gz
Processing dulwich-0.8.3.tar.gz
Running dulwich-0.8.3\setup.py -q bdist_egg --dist-dir c:\users\***\appdata\local\temp\easy_install-ghb21p\dulwich-0.8.3\egg-dist-tmp-sc0we9
error: Setup script exited with error: Visual Studio Express: need 64-bit tools from the SDK

Windows SDKの64bit版C++ Compilerをインストールしろ、ということなのですが、罠があります。最新のSDKをインストールしても解消しません。

MathWorks 日本 – How can I set up Microsoft Visual Studio 2008 Express Edition for use with MATLAB 7.7 (R2008b) on 64-bit Windows? – MATLAB & Simulink

こちらの情報によると、「Windows SDK for Windows Server 2008 and .NET Framework 3.5」か、「Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1」でないとダメのようです。

今回は「Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1」をインストールして成功しました。SDKのインストールの最後に致命的エラーとか表示されましたが、特に問題はなかったようです。

これで再度、easy_install hg_gitを実行すれば、

Installed c:\python27\lib\site-packages\dulwich-0.8.3-py2.7-win-amd64.egg

Finished processing dependencies for hg-git

となって、インストールがやっと成功しました。

最後に%userprofile%\mercurial.iniを開いて、

[extensions]

bookmarks =

hggit = C:\Python27\Lib\site-packages\hg_git-0.3.2-py2.7.egg\hggit

のようにhggitの場所を指定してやればOKです。


URLGrabberでFatal Python error: deallocating None

URLGrabberで数千件のURLをkeep-aliveで取得しようとすると、大体同じような回数でFatal Python error: deallocating Noneが出ることがあります。

どうやら、PycURLの参照カウントの問題らしいです。

パッケージでインストールされるものは古いので、PycURLを最新のソースからインストールしなおしましょう。以下、環境はDebian squeeze+python 2.6。

python-pycurlをすでにインストールしている場合はアンインストールしておく必要があります。

# aptitude install python-pycurl
でインストールしている場合は、
# aptitude purge python-pycurl
でアンインストールしておきましょう。

pycurlは最新のものをsourceforgeのCVSからダウンロードします。

SourceForge.net Repository – [pycurl] Index of /pycurl
下の方にある、「Download GNU tarball」のリンクからtarファイルをダウンロードできます。
ダウンロードしたファイルをpycurl.tar.gzなどに名前変更して、tar xvzf pycurl.tar.gzで展開できます。

ビルドにはcurl-configとPython.hなどが必要なので、必要なパッケージをインストールしておきます。

# aptitude install python2.6-dev libcurl4-gnutls-dev

pycurl.tar.gzを展開したら
# cd ./pycurl/
# python setup.py install
で、インストール完了です。

ちなみに、python2.6-devをインストールしていないと、
src/pycurl.c:42:20: error: Python.h
のようなエラーが大量に出ます。

とりあえずこれで、今のところ安定動作しています。


PythonのPyDHCPLibを使ってDHCPパケットを読む

PyDHCPLibはPure Pythonで書かれたDHCPパケットのリード/ライトライブラリです。

Pythonで書かれているので、LinuxでもWindowsでも動きます。(Windowsのときはちょっと対策が必要)

まずはdebian Linuxの場合。(aptでインストールできました。追記参照)

$ wget http://pydhcplib.tuxfamily.org/download/pydhcplib-0.6.2.tar.gz
$ tar xvzf pydhcplib-0.6.2.tar.gz
$ cd pydhcplib-0.6.2
$ sudo /usr/bin/python2.6 ./setup.py install

/usr/local/lib/python2.6/dist-packages/pydhcplib
に入りました。

流れてくるパケットを読み取るためにはサーバとして動かします。
examplesディレクトリの中にサーバ用のサンプルが入っているので実行します。

$ sudo /usr/bin/python2.6 ./examples/server_example.py

これでOKです。

ちなみにroot権限で実行しないと、以下のエラーが出てポートが開けられません。
pydhcplib.DhcpNetwork.BindToAddress error : [Errno 13] Permission denied

ではWindowsの場合。

Windows 7にもPython 2.7.2をインストールして使って見ました。

> cd pydhcplib-0.6.2
> C:\Python27\python.exe .\setup.py install

C:\Python27\Lib\site-packages\pydhcplibにインストールされました。

> C:\Python27\python.exe .\examples\server_example.py
Traceback (most recent call last):
  File ".\examples\server_example.py", line 21, in <module>
    from pydhcplib.dhcp_network import *
  File "C:\Python27\lib\site-packages\pydhcplib\dhcp_network.py", line 22, in <module>
    import IN
ImportError: No module named IN

インポートエラー。INモジュールというものがないとのこと。

INモジュールはdebianではPythonのplat-linux2ディレクトリ以下に入っています。中身は
# Generated by h2py from /usr/include/netinet/in.h
netinetから変換した定数の定義でした。

なので、必要なところだけコピーしてくることにします。

$ cat /usr/lib/python2.6/plat-linux2/IN.py |grep SO_BINDTODEVICE
SO_BINDTODEVICE = 25

このSO_BINDTODEVICEの定義だけを書いたIN.pyファイルをexamplesディレクトリに置けばOKです。

IN.py
SO_BINDTODEVICE = 25

これで試しにiPod touchをLANに接続して見ました。

> C:\Python27\python.exe .\examples\server_example.py
# Header fields
op : BOOTREQUEST
htype : 1
hlen : 6
hops : 0
xid : 3472825851
secs : 1
flags : 0
ciaddr : 0.0.0.0
yiaddr : 0.0.0.0
siaddr : 0.0.0.0
giaddr : 0.0.0.0
chaddr : 00:26:bb:XX:XX:XX
sname :
file :
# Options fields
client_identifier :
parameter_request_list : subnet_mask,router,domain_name_server,domain_name,domain_search,252
host_name : homma2
request_ip_address : 172.18.0.21
dhcp_message_type : DHCP_REQUEST
ip_address_lease_time : 7776000
maximum_dhcp_message_size : 1285

これでネットワークに接続された端末のリースタイム・MACアドレス・IPアドレスが取れました。

追記

debian squeezeではパッケージ登録されていました。
なので、aptで簡単にインストールできます。

$ aptitude search pydhcplib
p   python-pydhcplib                                                                                 – Python DHCP client/server library
v   python2.5-pydhcplib                                                                              –
v   python2.6-pydhcplib                                                                              –
$ sudo aptitude install python-pydhcplib

以上。


Pythonのwin32comからSilverlightを使おうと試みる

最終的にはPythonで書かれたWindowsアプリケーションで、Silverlightのコンテンツをロードしたいという目的なのですが、とりあえずSilverlightのActiveXコントロールを読み込んで動作を確認してみたいので色々実験。

まず、インストールされているSilverlightのバージョンを調べてみる。

Javascriptで書かれたコードがいくつか見つかったのでそれを書き直す。

以下はJS版。

var control = new ActiveXObject('AgControl.AgControl');
alert(control.IsVersionSupported('3.0'));

これをPythonで書いてみる。

import win32com.client
control = win32com.client.Dispatch("AgControl.AgControl")
print control.IsVersionSupported('3.0')

Silverlight 3がインストールされていればTrueが表示されます。

他にどんなメソッドが定義されているのかを調べるために、Visual StudioからAgControlを参照して、オブジェクトブラウザで調査。

というか、Silverlightのプラグインのリファレンスがあった。

Silverlight プラグインのオブジェクト リファレンス

が…Sourceを指定してもIsLoadedプロパティがTrueにならない…うーん…もう少し調べてみる。