Monthly Archives: 12月 2013

PythonでWindowsアプリケーションを作ってみよう

Pocket

Pythonには、pythonスクリプトを手軽にWindowsアプリケーション化できるツールが揃っている。
有名なのはPy2exeとPyInstallerである。
違いをまとめたうえで、PyInstallerでのWindowsアプリ化をまとめる。

Py2exeとPyInstallerの違い

サイト
http://www.pyinstaller.org/
http://www.py2exe.org/

  • インストールの容易さ
    →PyInstallerが有利
  • 対応Pythonバージョン
    →Py2exe: 2.4~3.1
    →PyInstaller: 2.4~2.7
  • 単独exeファイル作成の容易さ
    →PyInstallerがやや有利
  • 「manifest」ファイル埋め込みの容易さ
    →Py2exeが有利

手軽さの点でPyInstallerを選んだ。

PyInstallerの制限(日本語パスはダメ)

※2014/5/29追記
PyInstallerで生成したアプリには制限がある。
そのアプリを、日本語、要するにNon-ASCII文字列の含まれるパスに置くと起動に失敗する。
Python2なせいだと思うが、じゃあPython3で作ったらどうよ?と考えるも、そもそもPyInstallerはPython3に対応してないし…。
運用回避するしかないです。
作ったアプリを人に配って初めて気づいたよ。

PyInstallerのインストール

pyinstallerのインストールを参照。
ダウンロードして展開するだけ。
インストールっぽいことは不要。
追加でUPXがあれば準備するとよい。後述。

http://www.pyinstaller.org/ からダウンロード。
2013/12/6現在、最新版は2.1。

UPXのインストール

UPXとは、実行ファイルを、実行できる形式のまま圧縮してくれるツールである。
メリットはストレージの占有スペースを少なく出来ること。デメリットは実行時の展開処理。
UPXは実行時の展開処理がすごく速いうえにメモリ消費量も少ないとのこと。
大規模なプログラムだったら使ってもよいかな。

http://upx.sourceforge.net/‎
http://ja.wikipedia.org/wiki/UPX

UPX is a portable, extendable, high-performance executable packer for several 
different executable formats. It achieves an excellent compression ratio and 
offers *very* fast decompression. Your executables suffer no memory overhead 
or other drawbacks for most of the formats supported, because of in-place 
decompression.

インストールはごく簡単。
公式サイトからアーカイブをダウンロード。
Win32/i386版。
展開したらupx.exeが出てくるので、それをパスの通ったところに置くだけ。
Pythonのインストールされているディレクトリ(例: C:\Python27)の下に置くのがよいでしょう。
あるいは別ディレクトリに置いてそこにパスを通す。

PyInstallerの使い方

python pyinstaller.py targetscript.py とするだけである。

以下、詳細。
サンプルpythonスクリプトを一つ用意。
コマンドプロンプトを開いて展開したPyInstallerのディレクトリに移る。
cdで移るのが面倒なら、SHIFT+右クリックで開く。
pyicmdprmpt

pythonにパスが通っていることを確認。

C:\download\python\PyInstaller-2.1>python -V
Python 2.7.2

C:\download\python\PyInstaller-2.1>

対象スクリプトをpyinstallerのディレクトリに置くか、パスを取得する。
パスの取得は、対象ファイルをSHIFT+右クリックで出来る。

pyipthcp

C:\download\python\PyInstaller-2.1>python pyinstaller.py "C:\download\python\reducer.py"
1215 INFO: wrote C:\download\python\PyInstaller-2.1\reducer\reducer.spec
1559 INFO: Testing for ability to set icons, version resources...
1901 INFO: ... resource update available
2413 INFO: UPX is available.
(中略)
7048 INFO: Extending PYTHONPATH with C:\download\python
7049 INFO: checking Analysis
7050 INFO: building Analysis because out00-Analysis.toc non existent
7050 INFO: running Analysis out00-Analysis.toc
7054 INFO: Adding Microsoft.VC90.CRT to dependent assemblies of final executable
(中略)
21276 INFO: Executing - upx --lzma -q C:\Users\xxxxxx\AppData\Roaming\pyinstall
er\bincache01_py27\_socket.pyd

C:\download\python\PyInstaller-2.1>

 

Windowsプログラムのできあがり

PyInstallerのフォルダに、スクリプト名でフォルダが出来ているはず。
pyiblddn

その下に、さらにbuildとdistという、二つのフォルダがある。
他人にプログラムを配る場合には、distフォルダの下にある方を配ること。
実行に必要なDLL(pythonのDLL, MSVCRのDLL)もセットになっているので。

pyidist

その他のオプション説明

以下参照。
http://pythonhosted.org/PyInstaller/

以下にピックアップ。

-w, –windowed
実行時にコマンドプロンプトを開かないようになる。
GUIプログラムのときに便利。

-F, –onefile
プログラムを一つにまとめてくれる。
なかなか魅力的なオプションだが、プログラム実行時にけっこう時間がかかってしまう。
(試してみると分かるが、イライラするレベル)
おすすめしない。

-i <アイコンファイル>, –icon=<アイコンファイル>
プログラムのアイコンを設定できる。アイコンは拡張子.icoのファイル。

-y
–clean
-yは既存の実行ファイルを問答無用で上書きする。
修正しては何回も実行ファイルを作るときには便利。
–cleanはログファイルや作業ファイルを消してから実行ファイル作成を始める。

–noupx
UPXを使いたくないときに指定。

日常使いのpkgng:pkgを探してインストール

Pocket

インストールしたいpkgがある場合、どのように探すか。
pkg searchに与えるオプションを変えながら探していく。
sageというpkgを探す場合を例に取って記録しておく。

まずはsearchから

pkg seach sageですな。

$ pkg search sage
dosage-2.6
gmessage-0.2_5
gxmessage-2.12.4_1
nagios-check_cpu_usage-1.0
p5-AnyEvent-MessagePack-0.19
p5-CGI-Application-Plugin-MessageStack-0.34
p5-Catalyst-Plugin-StatusMessage-1.002000
p5-Data-MessagePack-0.48
p5-Data-MessagePack-Stream-0.07_1

山のように引っかかって面倒。
検索する文字列を考慮してみよう。

searchで正規表現

正規表現が使えるので、頭にsageとつくpkgを探す。”^sage”を与えればよいですな。

$ pkg search "^sage"
sage-0.2.0_3

一件になった。
ではインストール…の前に必ず確認。

インストールしていないpkgの詳細を知る

インストール済みのpkgであればpkg infoで調べることができる。
未インストールならどうするか。
-fを付ければよい。

$ pkg search -f "^sage"
sage-0.2.0_3
Name           : sage
Version        : 0.2.0_3
Origin         : graphics/sage
Prefix         : /usr/local
Categories     : graphics devel
Maintainer     : oliver@FreeBSD.org
WWW            : http://www.worldforge.org/dev/eng/libraries/sage
Comment        : OpenGL extension library
Shared Libs required:
        libSDL-1.2.so.11
Shared Libs provided:
        libsage.so.2
Flat size      : 953KiB
Pkg size       : 96 KB
Description    :
Sage is an OpenGL extension library written to make use of SDL's mechanism for
enabling OpenGL's extensions.

WWW: http://www.worldforge.org/dev/eng/libraries/sage

欲しいsageは数学関連のものなので、どうも違うようですな。
危なかった!
しかし狙いのsageは無いのだろうか。

カテゴリで探す

pkgはカテゴリ分けされている。
狙いのsageは数学関連であるから、おそらくmathの下にあるはずだ。

$  pkg search "^math/"|less
math/R
math/R-cran-ChangeAnomalyDetection
math/R-cran-Formula
(略)

あるいは:

$ pkg search "math\/"|less
math/R
math/R-cran-ChangeAnomalyDetection
math/R-cran-Formula
(略)

しかし。
ありませんでした。

$ pkg search "math\/"|grep sage|wc -l
       0
$

仕方がないのでportsでインストールしよう。

math/sageはportsにはないのだろうか。
psearchを使う。

$ psearch "^sage"
graphics/sage             OpenGL extension library
math/sage                 Open source Mathematics software

あった。

portsでのインストールは最小限に。

しかしportsからインストールするソフトウェアは最小限にしたい。
つまりmath/sageだけはportsを使ってもよいが、依存するものはpkgを使いたい。
本命ではない依存ソフトウェアのコンパイルなど待ちたくないし。

portmasterを使うなら-Pを与えればよい。
以下、portmasterのman抜粋。

     -P|--packages
         use packages, but build port if not available

 

$ sudo portmaster -P math/sage
(中略)
===>>> Initial dependency check complete for math/sage
===>>> math/sage >> (15)
===>>> The following actions will be taken if you choose to proceed:
        Install math/sage
        Install devel/autoconf
        Install devel/autoconf-wrapper
        Upgrade pkg-1.1.4_10 to pkg-1.2_1
        Install devel/gmake
        Install devel/m4
        Install misc/help2man
        Install devel/p5-Locale-gettext
        Install math/atlas
        Install print/teTeX-base
        Install print/teTeX-texmf
        Install print/font-amsfonts
        Install print/tex-texmflocal
        Install textproc/texi2html
        Install www/libwww
        Install devel/libtool

===>>> Proceed? y/n [y] n

pkgのアップグレードも提案された。
嫌な予感しかしない。
pkgのアップグレードはやめよう。
いったんNで抜ける。

portmasterで特定のportsのアップグレードを抑止したい。

-xオプションを使う。
portmasterのmanから抜粋。

$ portmaster --version
===>>> Version 3.17.3
$ man portmaster
     -x  avoid building or updating ports that match this pattern.  Can be
         specified more than once.  If a port is not already installed the
         exclude pattern will be run against the directory name from
         /usr/ports.

 

$ sudo portmaster -P -x pkg math/sage
(中略)
===>>> Initial dependency check complete for math/sage
===>>> math/sage >> (14)
===>>> The following actions will be taken if you choose to proceed:
        Install math/sage
        Install devel/autoconf
        Install devel/autoconf-wrapper
        Install devel/gmake
        Install devel/m4
        Install misc/help2man
        Install devel/p5-Locale-gettext
        Install math/atlas
        Install print/teTeX-base
        Install print/teTeX-texmf
        Install print/font-amsfonts
        Install print/tex-texmflocal
        Install textproc/texi2html
        Install www/libwww
        Install devel/libtool

意図した通りpkgのupgradeが外れている。
ただ…pkgレポジトリのものよりportsのバージョンが新しいとやっぱりportsが選ばれてしまう。

[報告]pkg-1.2.3でproxy越しのレポジトリ接続が可能に

Pocket

pkgngのレポジトリがsrvレコードなせいで、proxy越しだったりするとpkgがダウンロードできない問題があった。

2013/12/19現在のpkg-1.2.3でこの件が修正されている。
したがって、デフォルトの設定ファイル/etc/pkg/FreeBSD.confをそのまま使うことが出来る。

以下のような状態で、つまり、FreeBSD.confが有効(enabled:yes)になっている状態で;

$ pkg -vv
Version                 : 1.2.3
(中略)
Repositories:
  FreeBSD: {
    url             : "pkg+http://pkg.FreeBSD.org/freebsd:10:x86:64/latest",
    enabled         : yes,
    mirror_type     : "SRV",
    signature_type  : "FINGERPRINTS",
    fingerprints    : "/usr/share/keys/pkg"
  }
  us-west: {
    url             : "http://pkg0.isc.freebsd.org/freebsd:10:x86:64/latest",
    enabled         : no
  }
$

pkg updateが問題なくできる。

$ sudo pkg update
Updating repository catalogue
digests.txz                         100% 1042KB 347.5KB/s 512.4KB/s   00:03
packagesite.txz                     100% 5491KB 499.1KB/s 610.6KB/s   00:11
Incremental update completed, 22191 packages processed:
0 packages updated, 0 removed and 22191 added.

ああよかった。
こちらからは以上です。

(追記)
FreeBSD-9.xの場合には以下の内容を/usr/local/etc/pkg/repos/FreeBSD.confとして保存すればよい。

FreeBSD: {
  url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
  mirror_type: "srv",
  enabled: yes
}

 

No tags for this post.

Graphvizでカックいいグラフを描こう

Pocket

Graphvizとは、AT&T研究所の作ったグラフ描画ソフトである。
ここでのグラフとは棒グラフのグラフではなく、ソーシャルグラフとかのグラフである。
点(ノード)と線(エッジ)で表されるもので、例えば、何らかの状態遷移や、路線図や、ネットワークなどの「関係」の表現に使われる。

もともとオイラーの一筆書きのような経路探索の分野があって、それを視覚的に表現するためのツールとしてこういったソフトがある(たぶん)。
そんな分野はとても手に負えない。
しかし、グラフ描画に注目するだけでも、とても面白いんである。

例えば、ふだん利用する路線の、各駅の関係と乗降数をグラフに書いてみるだけでも、表で見たときは比べ物にならないくらいのインパクトがある。

keikyu
これは、京浜急行の駅の繋がりと乗降者数をグラフにしてみたもの。
隣り合う駅は繋ぐし、特急などで途中の駅をすっ飛ばす場合も繋ぐ。
乗降者数に応じて駅の大きさを変えてみた。
(何気なく作ったら一辺が10,000ピクセルを超える巨大画像になったので泣く泣く縮小した。)

そういったわけで、この記事では(Python経由で)graphvizのグラフ描画についてまとめた。

以下、特に指定のないかぎり、グラフと記載があれば、それは上記の意味でのグラフである。

Graphvizについて

手っ取り早くどんなグラフが描けるのかを知りたければこちらのサンプルグラフなどを。

関連のwebsiteは以下のとおり。

Graphviz(公式) http://www.graphviz.org/
Graphviz(wiki) http://ja.wikipedia.org/wiki/Graphviz

Graphvizでは、DOTという形式でグラフを描画する。
しかしDOT形式をそのまま扱うのはちょっと難しい。
そこで他の言語を通して使う。
具体的にはpygraphviz。
PyGraphvizはGraphvizのpythonインタフェースである。

PyGraphvizのインストール

FreeBSD, OS Xでのインストールは確認済みである。
しかし意外や意外、WindowsのActivePythonではPyGraphvizをインストールできない。PyPMにないのである。
素のPythonなら出来るのかもしれないが。

しかし、Graphviz単体ならインストールできる。DOT形式のファイル(以降、DOTファイル)を別マシンからもらえば、WIndows上でもグラフ描画は可能。

FreeBSDでのインストール

portsでもpkgでも、pygraphvizで探せば出てくるのでそれをインストールすればよい。
以下はpkgでの例。
gccを連れてきてダウロードサイズが100MBを超えた。驚いた。
ついでnumpyも入れた。

$ pkg search graphviz
graphviz-2.34.0
py27-graphviz-1.1_1
rubygem-graphviz-1.0.9
trac-graphviz-0.7.4_6
$ sudo pkg install py27-numpy py27-graphviz
Updating repository catalogue
The following 12 packages will be installed:

        Installing mpc: 1.0.1
        Installing gcc-ecj: 4.5
        Installing binutils: 2.23.2
        Installing py27-nose: 1.3.0
        Installing libgd: 2.1.0_1,1
        Installing gcc: 4.6.4
        Installing graphviz: 2.34.0
        Installing blas: 3.4.2_1
        Installing py27-graphviz: 1.1_1
        Installing lapack: 3.4.2_1
        Installing suitesparse: 4.0.2_2
        Installing py27-numpy: 1.7.0_2,1

The installation will require 685 MB more space

110 MB to be downloaded

 

OS Xでのインストール

graphvizをインストールし、そのあとPython上でpygraphvizをインストールすればよろし。
以下の例ではbrewでgraphvizを、そのあとpipでpygraphvizをインストールしている。

$ brew install graphviz
==> Downloading http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.3
######################################################################## 100.0%
==> Downloading patches
<snip>
==> make install
/usr/local/Cellar/graphviz/2.30.1: 462 files, 10M, built in 3.1 minutes
$

$ pip install pygraphviz
Downloading/unpacking pygraphviz
  Using download cache from /Users/xxx/.pip/cache/https%3A%2F%2Fpypi.python.org%2Fpackages%2Fsource%2Fp%2Fpygraphviz%2Fpygraphviz-1.2.tar.gz
  Running setup.py egg_info for package pygraphviz
    Trying pkg-config
    library_path=/usr/local/Cellar/graphviz/2.30.1/lib
    include_path=/usr/local/Cellar/graphviz/2.30.1/include/graphviz
<snip>
    no previously-included directories found matching 'doc/build'
Successfully installed pygraphviz
Cleaning up...
$

 

Windowsでのインストール(graphvizだけ)

WindowsのActivePythonではpygraphvizが使えない。
素のgraphvizをインストールする。
以下あたりからダウンロードする。

http://www.graphviz.org/Download_windows.php

インストーラがよければmsiを、レジストリを汚したくないならzipをダウンロード。
zipは展開するとreleaseというフォルダが出来る。
リネームしてどこにでも置けばよい。
実行ファイルはbinの下にある。
必要ならパスを通しておく。

実際に使う実行ファイルはdot、circo、neatoあたりでしょう。

pygraphvizインストールの確認

pygraphvizをimportしてみてエラーの出ないことを確認しておこう。
たとえばIDLEで。

Python 2.7.5 (default, Oct 17 2013, 07:35:17)
[GCC 4.2.1 Compatible FreeBSD Clang 3.3 (tags/RELEASE_33/final 183502)] on freebsd10
Type "copyright", "credits" or "license()" for more information.
>>> import pygraphviz
>>>

 

PyGraphvizを使ってみよう。

基本はここのチュートリアルに沿えばよい。
http://networkx.lanl.gov/pygraphviz/tutorial.html

pygraphvizをimportし、AGraphクラスを作る。

import pygraphviz as pgv
G = pgv.AGraph()

ノードの追加

G.add_node('a')
G.add_node('b')

エッジの追加

G.add_edge('c','d')
G.add_edge('e','f')

そして描画。
layoutを指示すると各ノード、エッジの配置がなされ、drawで画像に書き込める。

G.layout()
G.draw('sample01.png')

dotファイルを書き出すには。

G.write("sample01.dot")

 

サンプルスクリプト

以下、サンプルスクリプトとその結果つくられるグラフを列挙する。
先述の通りWindowsではpygraphvizが使えない。
Windowsでグラフを描こうとするなら、MacやFreeBSD他、pygraphvizで生成しておいたdotをWindows上のgraphvizで読みこむしかない。
その方法は最後に触れる。

サンプル1

#!/bin/env python

import pygraphviz as pgv

G = pgv.AGraph()

G.add_node('a')
G.add_node('b')

G.add_edge('c','d')
G.add_edge('e','f')

G.layout()
G.draw('sample01.png')

sample01

サンプル2

ノードの追加は、リストでまとめてできる。

#!/bin/env python

import pygraphviz as pgv

G = pgv.AGraph()

nodelist = ['g','h','i']

G.add_nodes_from(nodelist)

G.add_edge('c','d')
G.add_edge('e','f')

G.layout()
G.draw('sample02.png')

sample02

サンプル3

同じエッジを二回追加しても変わらない。

#!/bin/env python

import pygraphviz as pgv

G = pgv.AGraph()

nodelist = ['g','h','i']

G.add_nodes_from(nodelist)

G.add_edge('h','i')
G.add_edge('h','i')

G.layout()
G.draw('sample03.png')

sample03

サンプル4

しかし、最初のクラス作成時にstrict=Falseと指定すれば。

#!/bin/env python

import pygraphviz as pgv

G = pgv.AGraph(strict=False)

nodelist = ['g','h','i']

G.add_nodes_from(nodelist)

G.add_edge('h','i')
G.add_edge('h','i')

G.layout()
G.draw('sample04.png')

sample04
二本になる。

サンプル5

さらにdirectを指定すれば。

#!/bin/env python

import pygraphviz as pgv

G = pgv.AGraph(strict=False, directed=True)

nodelist = ['g','h','i']

G.add_nodes_from(nodelist)

G.add_edge('h','i')
G.add_edge('h','i')

G.layout()
G.draw('sample05.png')

sample05
矢印になる。

サンプル6

ここまでは殺風景であったが、色だって形だって変更できる。

#!/bin/env python

import pygraphviz as pgv

G = pgv.AGraph(strict=False, directed=True)

nodelist = ['g','h','i']

G.add_nodes_from(nodelist)

G.add_edge('h','i')
G.add_edge('h','i')

G.layout()
G.draw('sample05.png')

sample06

 

参考

ここから先は、以下を参考にして各自素敵なグラフを作ってくれたまえ。
https://github.com/pygraphviz/pygraphviz/blob/master/examples/miles.py

pygraphviz attrの一覧
http://www.graphviz.org/doc/info/attrs.html

Windowsでdotからグラフを描画する。

インストールしたdot, circo, neatoのいずれかに、-Tで出力形式を、-oで出力ファイル名を指定したうえで、dotファイルを与えればよい。

dot -Tpng -o filename.png filename.dot
circo -Tpng -o filename.png filename.dot
neato -Tpng -o filename.png filename.dot

 

 

No tags for this post.

[メモ]zpoolのupgrade

Pocket

 

zpoolのupgradeをしたのでメモ。
結論としては、zpoolのupgradeとは、単にversionを上げるだけ以外にもあるようだ。

legacy on-disk formatでformat??

気がつくと、zpool statusで文句を言われていた。

$ zpool status
  pool: vault
 state: ONLINE
status: The pool is formatted using a legacy on-disk format.  The pool can
        still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the
        pool will no longer be accessible on software that does not support feature
        flags.
(略)

曰く、「このpoolはlegacy on-disk formatでフォーマットされている。
もちろんpoolは引き続き使えるけれども、いくかの機能が使えない。」とのこと。

zpoolを調べてみたが、最新のv28である。

$ zpool get all|grep vault
vault      size                   2.27T                  -
vault      capacity               64%                    -
vault      health                 ONLINE                 -
vault      version                28                     local
(略)

 

zpool upgradeで調べて分かってきた。
zpoolバージョンではなくfeature flagsのことを言っているわけだ。

$ zpool upgrade
This system supports ZFS pool feature flags.

The following pools are formatted with legacy version numbers and can
be upgraded to use feature flags.  After being upgraded, these pools
will no longer be accessible by software that does not support feature
flags.

VER  POOL
---  ------------
28   vault

Use 'zpool upgrade -v' for a list of available legacy versions.
Every feature flags pool has all supported features enabled.

 

で、もういちど調べてみると。

$ zpool get all|grep vault
vault      size                   2.27T                  -
vault      capacity               64%                    -
vault      health                 ONLINE                 -
vault      version                28                     local
(略)
vault      feature@async_destroy  disabled               local
vault      feature@empty_bpobj    disabled               local
vault      feature@lz4_compress   disabled               local

featureがいくつかdiabledになっている。
そうと分かれば素直にupgradeである。

zpoolのupgrade

zpool upgradeとするだけ。
ただ、バージョンが変わらないとはいえ、ファイルシステムの基盤をアップグレードするわけだからバックアップは取っといた。

$ sudo zpool upgrade vault
This system supports ZFS pool feature flags.

Successfully upgraded 'vault' from version 28 to feature flags.
Enabled the following features on 'vault':
  async_destroy
  empty_bpobj
  lz4_compress

あっけなく終了。

調べてみるとversionが消えて(なぜ….でもpropertiesがdefaultだからよしとしよう)、その代りfeatureはすべてenabledに変化したことが分かる。
なお、enabledは「その機能が使えますよ」という表示。
実際に有効にするとenabledはactiveに変化する。

$ zpool get all|grep vault
vault      size                   2.27T                  -
vault      capacity               64%                    -
vault      health                 ONLINE                 -
vault      version                -                      default
(略)
vault      feature@async_destroy  enabled                local
vault      feature@empty_bpobj    enabled                local
vault      feature@lz4_compress   enabled                local

 

zpool upgrade、zpool statusの表示いずれも問題なし。

$ zpool upgrade
This system supports ZFS pool feature flags.

All pools are formatted using feature flags.

Every feature flags pool has all supported features enabled.

$ zpool status
  pool: vault
 state: ONLINE
  scan: scrub repaired 0 in 4h53m with 0 errors on Sat Jul 27 14:35:23 2013
config:

        NAME        STATE     READ WRITE CKSUM
        vault       ONLINE       0     0     0
          ada1      ONLINE       0     0     0

errors: No known data errors

 

No tags for this post.

[メモ] ディスクを追加してZFSを作り、他zpoolのsnapshotを送り込む

Pocket

 

HDDを増設してZFSを作ったのでメモ。
一本のHDDにpool、zfsを作成し、圧縮、重複排除機能の有効化まで。
環境は(残念ながら10.0-Rではなく)FreeBSD 9.2-RELEASE-p1。

lz4でzfsの圧縮機能を気軽に試せるように

ファイルシステムで圧縮機能を有効にすると、読み書きのいずれにもCPUパワーが必要で、要するに遅くなる。
非力なCPUを使っているとなかなか使いにくい機能なのだが、圧縮方法にlz4が選べるようになってハードルは下がったように思う。
lz4はここでも触れたが、めっぽう速い圧縮アルゴリズムである。
これはぜひとも使ってみなければ。

 

 

ディスクの確認とzfs機能の確認

物理ディスクを追加し、ブートしたらdmesgを確認する。

$ uname -r
9.2-RELEASE
$ dmesg|grep ada
ada2 at ahcich2 bus 0 scbus2 target 0 lun 0
ada2: <WDC WD30EZRX-00D8PB0 80.00A80> ATA-9 SATA 3.x device
ada2: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada2: Command Queueing enabled
ada2: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C)
ada2: quirks=0x1<4K>
ada2: Previously was known as ad8

ada2とのこと。

作業前にzfs, zpoolのバージョンを確認しておいてもいいかも。
zfs, zpoolそれぞれにupgradeオプションを与えればよい。
upgradeという名前の通り、upgradeのためのコマンドだが、バージョン確認にも使える。

$ zfs upgrade
This system is currently running ZFS filesystem version 5.

All filesystems are formatted with the current version.
$
$ zpool upgrade
This system supports ZFS pool feature flags.

The following pools are formatted with legacy version numbers and can
be upgraded to use feature flags.  After being upgraded, these pools
will no longer be accessible by software that does not support feature
flags.

VER  POOL
---  ------------
28   vault

Use 'zpool upgrade -v' for a list of available legacy versions.
Every feature flags pool has all supported features enabled.

zfsはバージョン5、zpoolはバージョン28。
このバージョンであれば、lz4による圧縮機能(LZ4 Compression algorithm support)と、重複排除機能(Deduplication)を使える。

pool、zfsの作成

warehouseというzpoolを作り、そこからbackupというボリュームを切り出す。

まずzpoolを作る。
ほんと簡単で速くて助かる。

$ sudo zpool create backup /dev/ada2
$

で確認。

$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
backup on /backup (zfs, local, nfsv4acls)

$ zpool status
pool: backup
state: ONLINE
scan: none requested
config:

NAME        STATE     READ WRITE CKSUM
backup      ONLINE       0     0     0
ada2      ONLINE       0     0     0

errors: No known data errors

pool: vault
state: ONLINE
(略)

$ df
 Filesystem     1K-blocks      Used      Avail Capacity  Mounted on
 /dev/ada0p2    239436440  20822200  199459328     9%    /
 devfs                  1         1          0   100%    /dev
 vault/itunes  1436646199 598670122  837976077    42%    /itunes
 vault/chamber 1796007595 958031518  837976077    53%    /chamber
 warehouse     2873622450        31 2873622419     0%    /warehouse

ではzpoolからzfsの切り出し。
先ほど作成したwarehouseからbackupという名前で。

$ sudo zfs create warehouse/backup
$
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
warehouse on /warehouse (zfs, local, nfsv4acls)
warehouse/backup on /warehouse/backup (zfs, local, nfsv4acls)
$ df
Filesystem        1K-blocks      Used      Avail Capacity  Mounted on
/dev/ada0p2       239436440  20823572  199457956     9%    /
devfs                     1         1          0   100%    /dev
vault/itunes     1436646199 598670122  837976077    42%    /itunes
vault/chamber    1796007595 958031518  837976077    53%    /chamber
warehouse        2873622404        32 2873622372     0%    /warehouse
warehouse/backup 2873622403        31 2873622372     0%    /warehouse/backup

あとは/etc/fstabに書くだけ。
warehouse/backupを/backupにマウントするとして以下のように書いておき。

warehouse/backup        /backup zfs     rw      0       0

/warehouse/backupをいったんunmountしてそれからmount。

$ sudo umount /warehouse/backup
$
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
warehouse on /warehouse (zfs, local, nfsv4acls)
$
$ sudo mount /backup
$
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
warehouse on /warehouse (zfs, local, nfsv4acls)
warehouse/backup on /backup (zfs, local, nfsv4acls)

 

圧縮機能と重複排除機能を有効に

ではさっそく圧縮機能と重複排除機能を有効にする。
といっても、すっごく簡単なんだけどね。

$ sudo zfs set dedup=on warehouse/backup
$
$ sudo zfs set compression=lz4 warehouse/backup
$

確認。
zfs getで対象zfsの属性を確認できる。

$ zfs get dedup warehouse/backup
NAME              PROPERTY  VALUE          SOURCE
warehouse/backup  dedup     on             local
$
$ zfs get compression warehouse/backup
NAME              PROPERTY     VALUE     SOURCE
warehouse/backup  compression  lz4       local
$

タイプが面倒ならzfs get allですべての属性を表示させ、grepすればよい。

$ zfs get all warehouse/backup|egrep "compre|ded"
warehouse/backup  compressratio         1.00x                    -
warehouse/backup  compression           lz4                      local
warehouse/backup  dedup                 on                       local
warehouse/backup  refcompressratio      1.00x                    -

 

書き込んでみる

今回追加したHDDはもともとバックアップ用途のつもり。
ここにスナップショットを流しこんでみる。

以下のようにしてスナップショットを作成する。

$ sudo zfs snapshot vault/itunes@`date +%Y%m%d`
$
$ sudo zfs snapshot vault/chamber@`date +%Y%m%d`

スナップショットのサイズは以下のとおりである。

$ zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
vault/chamber@20131121      0      -   914G  -
vault/itunes@20131121       0      -   571G  -

これらスナップショットをバックアップのHDDに流し込む。
zfs sendとzfs recvをパイプで繋ぐ必要がある。
sudoを使う場合にはsh -cで。

$ sudo sh -c "zfs send vault/chamber@20131121 | zfs recv warehouse/backup/chamber"

注意点がある。
以上のようにsnapshotを送ると、受け側では:
①warehouse/backup/chamber ができ、さらに;
②warehouse/backup/chamber@20131121 つまり;
実ディレクトリで言えばwarehouse/backup/chamber/.zfs/snapshot/20131121ができる。

漠然とvault/chamber@20131121の内容がwarehouse/backup/chamberに書き込まれる思っていたので驚いた。

 

また、ロードアベレージを監視するような仕組みは特に入れていなかったので、topの出力を見たところ5を超えてた。ちょっと怖い。

last pid: 10483;  load averages:  5.37,  2.84,  1.36           up 2+23:24:54  22:01:40
45 processes:  3 running, 42 sleeping
CPU:  0.0% user,  0.0% nice, 56.8% system,  0.3% interrupt, 42.9% idle
Mem: 20M Active, 96M Inact, 1592M Wired, 11M Cache, 200M Buf, 120M Free
ARC: 1039M Total, 58M MFU, 826M MRU, 103M Anon, 11M Header, 40M Other
Swap: 907M Total, 10M Used, 897M Free, 1% Inuse

そしてたかだか913GBのsnapshotの転送にかかった時間であるが。

real    3756m59.109s
user    0m0.048s
sys     192m3.897s

まる二日半て…。
これは圧縮か重複排除か、どちらか止めた方がいいかもわからんね。

差分snapshotの転送

オリジナルディスクで複数回snapshotを作成した場合、バックアップディスクにはその差分を送ることができる。
zfs sendに-iを与え、二つのsnapshotを指定すればよいだけ。

$ sudo sh -c "zfs send -i vault/chamber@20131121 vault/chamber@20131125 | zfs recv warehouse/backup/chamber"

以上

qjailならjailのユーザランド更新にmake worldは不要ッ!

Pocket

 

この件があって、jailはqjailで管理している。
上記記事では触れなかったのだが、qjailにはもう一つ大きな利点がある。
qjailでは、jailのユーザランド更新にmake buildworldが不要なのである。
細かいところは後で述べる。
まずその使い方から。

qjailでのユーザランド更新

jailを止めたあとに、qjail update -bだけでOK。
jailを止めないで実行しようとしても、下記のように怒られる。
update -bはすぐに終わる。

$ sudo qjail update -b
Error: All jails have to be stopped.
This jail is running. example01
]$ sudo qjail stop example01
Jail successfully stopped  example01

$ sudo qjail update -b

Deletion of sharedfs binaries successful for bin.
Deletion of sharedfs binaries successful for lib.
Deletion of sharedfs binaries successful for libexec.
Deletion of sharedfs binaries successful for sbin.
Deletion of sharedfs binaries successful for usr/bin.
Deletion of sharedfs binaries successful for usr/include.
Deletion of sharedfs binaries successful for usr/lib.
Deletion of sharedfs binaries successful for usr/libdata.
Deletion of sharedfs binaries successful for usr/libexec.
Deletion of sharedfs binaries successful for usr/sbin.
Deletion of sharedfs binaries successful for usr/lib32.

Copied host's binaries to sharedfs successfully for bin.
Copied host's binaries to sharedfs successfully for lib.
Copied host's binaries to sharedfs successfully for libexec.
Copied host's binaries to sharedfs successfully for sbin.
Copied host's binaries to sharedfs successfully for usr/bin.
Copied host's binaries to sharedfs successfully for usr/include.
Copied host's binaries to sharedfs successfully for usr/lib.
Copied host's binaries to sharedfs successfully for usr/libdata.
Copied host's binaries to sharedfs successfully for usr/libexec.
Copied host's binaries to sharedfs successfully for usr/sbin.
Copied host's binaries to sharedfs successfully for usr/lib32.

Host to sharedfs binaries update completed successfully.
$

 

qjail update -bとは

マニュアルから俺訳で引用すると:

freebsd-updateはホストしか調べてくれず、jailは対象外だ。ホストには最新の環境があるのに、jailのためにわざわざ make buildworld/installworldするのは次男の無駄無駄無駄。
だからして、ホストのバイナリをsharedfsにコピーできるようした。

 

原文は以下の通り。

 

     -b      The basic requirement of FreeBSD jails is the jail environment
             and the host run the same version of the systems binaries. Since
             the FreeBSD-update utility only inspects the host system to
             determine the systems RELEASE level it's not applicable in a
             jailed environment. Performing a make buildworld/installworld on
             sharedfs's source is such a waste of effort and resources after
             having done this already for the host system. This option makes
             the buildworld/installworld obsolete for the qjail environment.

             This option deletes all the system binaries from the sharedfs and
             them copies the host's system binaries to sharedfs. It's intended
             to be used after running the FreeBSD-update utility on the host
             to apply security updates or to upgrade the GENERIC host from one
             RELEASE to another newer RELEASE, or after performing a make
             buildworld/installworld on the host updating its system binaries.
             Basically update the host and copy your work to the sharedfs
             getting both environments synchronized.
(snip)

FreeBSD 10.0                     July 22, 2013                    FreeBSD 10.0

 

 

No tags for this post.

pkgng 1.2へのアップデートに伴うあれこれ。

Pocket

 

pkgngを1.2にアップデートしたら、設定ファイルの扱いが変わって、ちょっとした修正が必要になった。
それをまとめる。

まとめ。

  • pkgngを更新したらpkg upgradeを忘れずに
  • すべてコメントの設定ファイルは受け付けてくれない。
  • 設定ファイルでのキー指定は、”(クオート)で囲わないこと。

 

pkg のアップデートあり

pkg updateをしたら、やたら文句を言われる。

$ sudo pkg update
pkg: Invalid configuration format, ignoring the configuration file
Updating repository catalogue
digests.txz                         100% 1045KB 261.2KB/s 434.7KB/s   00:04
packagesite.txz                     100% 5537KB 276.9KB/s 177.0KB/s   00:20
pkg: Skipping malformed dependency docbook-xml
pkg: Skipping malformed dependency docbook
pkg: Skipping malformed dependency docbook-xml

そしてupgradeすると、pkgに更新があるとな。
1.2.1である。
pkgに更新がある場合には、まずpkgを更新し、そのあとpkg upgradeをせよ、とのお達し。

$ sudo pkg upgrade
pkg: Invalid configuration format, ignoring the configuration file
Updating repository catalogue
digests.txz                         100% 1045KB 261.2KB/s 504.7KB/s   00:04
New version of pkg detected; it needs to be installed first.
After this upgrade it is recommended that you do a full upgrade using: 'pkg upgrade'

Upgrades have been requested for the following 1 packages:

        Upgrading pkg: 1.1.4_10 -> 1.2.1

The upgrade will require 580 KB more space

2 MB to be downloaded

Proceed with upgrading packages [y/N]: y
pkg-1.2.1.txz                       100% 1942KB 323.7KB/s 282.3KB/s   00:06
Checking integrity... done
[1/1] Upgrading pkg from 1.1.4_10 to 1.2.1... done
$

 

pkg 1.2でアップデートができない。

pkgの更新は問題なく完了。
念のためもう一回pkg updateを試みるが、設定ファイルを読めないと怒られる。

$ sudo pkg update
pkg: Cannot parse configuration file!
$

どうも設定ファイルがおかしいようだ。
しかし現状、/etc/pkgの下や、/usr/local/etc/reposの下にも設定ファイルがあって訳の分からない状態だ。

調べた結果は以下のようなものだ。
pkgはREPOS_PATHで指定される全てのディレクトリから設定ファイルを探す。
デフォルトでは、/etc/pkgと/usr/local/etc/pkg/reposである。

詳しくは以下を参照。
http://lists.freebsd.org/pipermail/freebsd-questions/2013-November/254682.html

注意すべきは、すべてコメント文で出来ている設定ファイルがあると、”pkg: Cannot parse configuration file!”と言い出してそれ以上の処理をしてくれなくなることだ。
どうもバグのようだが。
1.2より前では文句だけだった。

私の場合、以下の通り/usr/local/etc/pkg.confがコメント文だけだったので、rmした。(RCSに保存しているので消したって平気)

$ grep -v "^#" /usr/local/etc/pkg.conf
$
$ sudo rm /usr/local/etc/pkg.conf
$

 

設定ファイルでのkey指定方法の変更

改めてpkg update。今度は問題なしか?

$ sudo pkg update
pkg: Warning: expecting a boolean for the 'enabled' key of the 'us-west' repo,  the value has been correctly converted, please consider fixing
Updating repository catalogue
digests.txz                         100% 1045KB 261.2KB/s 404.7KB/s   00:04
packagesite.txz                     100% 5537KB 276.9KB/s 187.0KB/s   00:20
Incremental update completed, 22233 packages processed:
0 packages updated, 0 removed and 22233 added.

今度は設定ファイルの内容に文句が付いた。
booleanを期待してたのに違うぞ、と。
文句だけなので進めはするが、気持ち悪いので修正する。
設定ファイルの中でenabledなどのキー指定からクオートを外せばよい。

before

us-west: {
        url:    "http://pkg0.isc.freebsd.org/${ABI}/latest",
        enabled:        "yes",
        mirror_type:    "none",
}

after

us-west: {
        url:    "http://pkg0.isc.freebsd.org/${ABI}/latest",
        enabled:        yes,
        mirror_type:    none,
}

 

pkg upgrade

そうしたら指定通りpkg upgradeを実行。
今度は問題なし。
通常のアップグレードのほかに、依存が変わったとかで再インストールの必要なものが結構あった。

$ sudo pkg upgrade
Updating repository catalogue
digests.txz                         100% 1045KB 149.2KB/s  54.7KB/s   00:07
Upgrades have been requested for the following 37 packages:

        Upgrading apr: 1.4.8.1.5.2 -> 1.4.8.1.5.3
(略)
        Reinstalling orca-2.32.1_2 (direct dependency changed)
        Reinstalling gnome2-2.32.1_5 (direct dependency changed)

The upgrade will require 2 MB more space

102 MB to be downloaded

Proceed with upgrading packages [y/N]: y

そしてまた、autoremoveで掃除をしておこう。

$ sudo pkg autoremove
Deinstallation has been requested for the following 6 packages:

        autoconf-2.69
        autoconf-wrapper-20130530
        gmake-3.82_1
        help2man-1.43.3_1
        m4-1.4.17,1
        p5-Locale-gettext-1.05_3

The deinstallation will free 5 MB

Proceed with deinstalling packages [y/N]:

 

余談

以下のようにpy27-distributeが邪魔だというので、pkg delete -f py27-distributeしてpkg upgradeした。

Checking integrity...pkg: WARNING: locally installed py27-distribute-0.6.35 conflicts on /usr/local/bin/easy_install with:
        - py27-setuptools-1.1.7_1

pkg: WARNING: locally installed py27-distribute-0.6.35 conflicts on /usr/local/bin/easy_install-2.7 with:
        - py27-setuptools-1.1.7_1

pkg: WARNING: locally installed py27-distribute-0.6.35 conflicts on /usr/local/lib/python2.7/site-packages/easy-install.pth.dist with:
        - py27-setuptools-1.1.7_1

 

No tags for this post.

ActivePythonでPythonパッケージを扱うにはPyPM

Pocket

 

PyPMはActivePythonのPythonパッケージマネージメントシステムである。
パッケージの提供はActiveState

ただ、すべてのパッケージが揃っているわけではなく、ものによってはコンパイルに失敗し、結果としてPyPMでは入手できないものもある。

たとえば2013/11/14現在、pygraphvizは入手できない。
http://code.activestate.com/pypm/pygraphviz/

pygraphviz is unavailable in PyPM, because there aren’t any builds for it in the package repositories.

前後したが、PyPMで揃えられるパッケージは以下のサイトで確認できる。
http://code.activestate.com/pypm/
また、PyPMにもパッケージ検索機能が備わっている。

PyPMの起動

ActivePythonをインストールすると、Python Package Manager(PyPM)というプログラムがスタートメニューにできているはず。
これがPyPM。
startmenu

プログラムとは言っても、実体はcmd.exeに引数を与えて実行するショートカットである。

C:\Windows\System32\cmd.exe /k title PyPM & pypm

実行すると、コマンドプロンプトが開く。
pypm

 

PyPMの使い方

以下を参照

http://docs.activestate.com/activepython/3.3/pypm.html

検索:
 pypm search <パッケージ>
インストール:
 pypm install <パッケージ>
削除:
 pypm uninstall <パッケージ>
更新:
 pypm upgrade
一覧:
 pypm list

 

実行例

matplotlibを検索、インストールしてみる。

検索

C:\Windows\system32>pypm search matplotlib
 boomslang    A thin layer over matplotlib that simplifies creation of common p
 brewer2mpl   Connect colorbrewer2.org color maps to Python and matplotlib
 descartes    Use geometric objects as matplotlib paths and patches
 ezplot       Remote Procedure interface to Matplotlib
 matplotlib   Python plotting package
 pygmyplot    Matplotlib wrapper plotting library
 pywcsgrid2   pywcsgrid2 is a python module to be used with matplotlib for disp
 root2matplot Tools to plot ROOT histograms using matplotlib
 sphinxreport SphinxReport : a report generator in python based on Sphinx and m
 webplotlib   A package for creating server-side charts/graphs using matplotlib
 wxmplot      high level wxPython Components for 2D plotting and image display

インストール

C:\Windows\system32>pypm install matplotlib
The following packages will be installed into "%APPDATA%\Python" (2.7):
 as.mklruntime-1.3 numpy-1.7.1 matplotlib-1.1.1
Get: [pypm-free.activestate.com] as.mklruntime 1.3
downloading: [===========>        ]  59% 19.0MB/32.1MB (1m18s; 55s left)

インストール済みのパッケージ一覧

C:\Windows\system32>pypm list
as.mklruntime 1.3   Intel MKL runtime files (Windows only)
matplotlib    1.1.1 Python plotting package
networkx      1.8.1 Python package for creating and manipulating graphs and net
numpy         1.7.1 NumPy: array processing for numbers, strings, records, and

 

プロキシの設定

もしインターネット接続がproxy越しの場合には、環境変数の設定が必要だ。
以下に記載のあるとおり。
http://docs.activestate.com/activepython/3.3/pypm.html#proxies-and-firewalls

PyPMを実行したあと、以下のように設定してから進めればよい。

C:\Windows\system32>set http_proxy=http://proxysomewhere.com:8080/

 

なお、activestateのサイト通りだとうまくいかなくて、経験的な結果として:

  •  ダブルクオーテーションで囲ったらダメ。
  •  (おそらく)URLの最後はスラッシュで終わらないとダメ。

使用例

C:\Windows\system32>set http_proxy=http://proxysomewhere.com:8080/

C:\Windows\system32>pypm install networkx
Get: [pypm-be.activestate.com] :repository-index:
Get: [pypm-free.activestate.com] :repository-index:
downloading: [=======>            ]  39% 2.5MB/6.4MB (10s; 17s left)

以上

No tags for this post.