MacBookAirをスリープ状態で放置すると電源が切れる時はPRAMクリアとSMCリセット

メモの類はMacVimのタブを開いて保存もせずにパパッと書き留めるのですが、そのままスリープさせて就寝、朝起きると電源が切れている。なんてことばかりでげんなりです。evernotevimモードがあればいいのに。

もしかしてそういうものなのかとも思ったけど、やはりおかしいのでググってみた。

こういう時は、PRAMクリアとSMCリセットをしてみろということらしい。

PRAMクリア

  1. 電源off
  2. Command + Option + P + R を押しながら電源を入れる
  3. 再起動して2回目の「じゃーん」が聞こえたらキーを離す

SMCリセット

  1. 電源off
  2. バッテリーを外す
  3. 電源ボタンを5秒間押し続ける
  4. 電源ボタンを放す
  5. バッテリーを付けて起動

MacBookAirの場合はバッテリーが取り外せないので、

  1. 電源off
  2. 電源アダプタを接続
  3. Shift + Control + Option を押しながら電源ボタンを5秒間押し続ける
  4. ボタンを離して起動する

という手順でいいらしい。

ひとまずPRAMクリアしてみたので、これで放置してみます。

(02/22追記:朝PRAMクリアして、14時間ほど放置してみたところ復帰出来ました。これで大丈夫かな)

編集中のファイルのメソッド一覧をQuickfixで縦分割して表示する

Quickfixは便利なんだけど、クラスファイルを編集中に縦分割でガバッと一覧で出して欲しかったのでこんなキーバインドを設定してみた。

nnoremap <buffer> <F1> :vs<CR>:vimgrep /^\s*function / %<CR>:cw<CR><C-w>k:q<CR><C-w>l

これを~/.vim/after/ftplugin/php.vimに登録。ただのキーボードマクロなんだけど、思ったより便利だったのでブログに書いておくことにする。

この例はPHPだけど、Perlならvimgrep対象をsubにすればいいし、PythonRubyならdefにすればOK。

CakePHPのSet::extractは引数の順番に寛容である

CakePHPにはSet::extractというPHPが不便なだけ非常に便利な機能があります。こいつの実装はなかなか面白いことになっていて、

<?php
public static function extract($path, $data = null, $options = array()) {
	if (is_string($data)) {
		$tmp = $data;
		$data = $path;
		$path = $tmp;
	}

と$dataがstringだったら$pathと入れ替えてくれます。引数の順番を間違えても平気です、安心ですね。もしかしたら昔は逆だったんでしょうか。「cakephp set::extract 引数 順番」でググったけど分かりません。

少なくとも今の時点では、CakePHP2.0にもこのコードは残っているので、後方互換性もバッチリなようです。E_WARNING、せめてE_NOTICEぐらい吐いてもよさそうに思いますが。

CentOS + Xenでdom-0のメモリ使用量を制限したり、8個以上のdom-Uを起動する

そろそろKVMだと言うのに、またも古いネタをブログに持ってくるの巻。

dom-0(母艦)のメモリ使用量を制限する

$ sudo yum install xen

とかやって、インストールした後に/etc/grub.confを編集。

初期状態ではXenカーネルで起動する設定になっていなかったりするので、defaultを変更してXenカーネルで起動するようにする(最初が1じゃなくて0なのに留意)。

で、カーネルの起動パラメータに「dom0_mem」を設定する。これで最初からdom-0に割り当てるメモリ量を制限できるのでリソース計画が立てやすい。

kernel /xen.gz-2.6.18-194.32.1.el5 dom0_mem=1000M

と書けばdom-0はメモリ1GB使用で固定される。

dom-Uを8個以上起動可能にする

loopbackデバイスが8個に制限されているのが原因なので、/etc/modprobe.confに以下のように書く。

options loop max_loop=16

これで16個までOK。

CentOS5系のsystem Perlでlocal::lib環境を作る方法

今更感がありすぎる古いネタでもブログに上げてしまおうキャンペーン実施中。今ならperlbrewを使うのが圧倒的にお勧めなのですが、system Perl(OSに標準で付いてくるPerl)の出番も完全に無くなるわけでもないかなーと。

例えば先日、CloudForecastをperlbrew環境で使おうと思ったらRRDtoolやらSNMPPerlバインディングのインストールが面倒で、system Perl + local::libでセットアップしたりしました。むしろperlbrew環境でサクサク入れる方法が知りたい。

それはさておき、x86_64なCentOS5系(多分どれも変わらないんじゃないかな)でOSインストール直後の状態からlocal::libをセットアップ時に自分がやってる手順をご紹介。繰り返しますが、明確な理由が無い限りはperlbrewを使うのがお勧めです。

以下、ユーザ名はryo、グループ名はadmin、CPANモジュールのインストール先は/usr/local/CPAN/を例に書いていますので適宜読み替えてください。



まずはインストール先のディレクトリを作っておく。

$ sudo install -o ryo -g admin -m 775 -d /usr/local/CPAN


次にlocal::libを入れたいけど、CentOS標準のPerl環境は古いので、まずは依存モジュールを入れてやる必要がある。要なモジュールは以下の通り。数値付きの物はそれ以降のバージョンが必要。

  • ExtUtils::MakeMaker 6.31
  • ExtUtils::Install 1.43
  • ExtUtils::CBuilder
  • ExtUtils::ParseXS
  • Module::Build 0.28
  • CPAN 1.80

上記をsystem Perl環境にインストールしてやる。

$ sudo cpan CPAN ExtUtils::MakeMaker ExtUtils::Install ExtUtils::CBuilder ExtUtils::ParseXS Module::Build

これを実行すると、~/.cpan/以下がroot所有になって具合が悪いので、一旦サクっと消してしまう。

$ sudo rm -rf ~/.cpan

cpanコマンドの設定は~/.cpan/CPAN/MyConfig.pmに入っていて、最初にcpanコマンドを起動したときに設問に答えていくとcpanコマンドがファイルを作ってくれる。けど、いちいち回答していくのはダルいのであらかじめ作っておいたファイルを直接配置する。

先ほど~/.cpanを消しているのでディレクトリも作らないといけない。ふつうに作ってもいいし、一度cpanコマンドを起動してCTRL+cで止めるとかでもよい。

で、~/.cpan/CPAN/MyConfig.pmは以下のようにする。

$CPAN::Config = {
  'auto_commit' => q[0],
  'build_cache' => q[10],
  'build_dir' => q[/home/ryo/.cpan/build],
  'build_requires_install_policy' => q[ask/yes],
  'cache_metadata' => q[1],
  'check_sigs' => q[0],
  'commandnumber_in_prompt' => q[1],
  'connect_to_internet_ok' => q[0],
  'cpan_home' => q[/home/ryo/.cpan],
  'ftp' => q[/usr/bin/ftp],
  'ftp_passive' => q[1],
  'ftp_proxy' => q[],
  'getcwd' => q[cwd],
  'gpg' => q[/usr/bin/gpg],
  'gzip' => q[/bin/gzip],
  'halt_on_failure' => q[0],
  'histfile' => q[/home/ryo/.cpan/histfile],
  'histsize' => q[100],
  'http_proxy' => q[],
  'inactivity_timeout' => q[0],
  'index_expire' => q[1],
  'inhibit_startup_message' => q[0],
  'keep_source_where' => q[/home/ryo/.cpan/sources],
  'load_module_verbosity' => q[v],
  'make' => q[/usr/bin/make],
  'make_arg' => q[],
  'make_install_arg' => q[],
  'make_install_make_command' => q[/usr/bin/make],
  'makepl_arg' => q[],
  'mbuild_arg' => q[],
  'mbuild_install_arg' => q[],
  'mbuild_install_build_command' => q[./Build],
  'mbuildpl_arg' => q[],
  'ncftp' => q[],
  'ncftpget' => q[],
  'no_proxy' => q[],
  'pager' => q[less],
  'perl5lib_verbosity' => q[v],
  'prefer_installer' => q[MB],
  'prerequisites_policy' => q[follow],
  'scan_cache' => q[atstart],
  'shell' => q[bash],
  'show_upload_date' => q[0],
  'tar' => q[/bin/tar],
  'tar_verbosity' => q[v],
  'term_is_latin' => q[1],
  'term_ornaments' => q[1],
  'trust_test_report_history' => q[0],
  'unzip' => q[/usr/bin/unzip],
  'urllist' => [q[ftp://ftp.riken.jp/lang/CPAN/], q[ftp://ftp.kddilabs.jp/CPAN/]],
  'use_sqlite' => q[0],
  'wget' => q[/usr/bin/wget],
  'yaml_load_code' => q[0],
};
1;
__END__

「'prerequisites_policy' => q[ask],」にすれば依存モジュールを勝手にインストールせず、都度確認を取るようになります。面倒なので自動で入れる設定にしているけど、気になる人は確認してもいいかも知れません。


これで準備は出来たので、いよいよlocal::libを入れる。http://search.cpan.org/からlocal::libを検索して、モジュール名じゃなくて「local-lib-1.008001」とかバージョンが表示されてる方のリンクをたどるとDownloadのリンクがあるページに直接行ける。

tar.gzをダウンロードしてきたら適当なディレクトリで展開して、cdして、インストールする。2011/02/11現在だとこんな感じ。

$ wget http://search.cpan.org/CPAN/authors/id/A/AP/APEIRON/local-lib-1.008001.tar.gz
$ tar zxf local-lib-1.008001.tar.gz
$ cd local-lib-1.008001
$ perl Makefile.PL --bootstrap=/usr/local/CPAN
$ make test && make install

気を付けるのはperl Makefile.PLする時に--bootstrapでディレクトリを指定することぐらいですね。cpanコマンドとかでモジュールを入れると、/usr/local/CPAN/以下にインストールされます。


セットアップしたlocal::libを使うには、

$ perl -I/usr/local/CPAN/lib/perl5 -Mlocal::lib=/usr/local/CPAN

を実行して得られる以下の出力を、.bashrcなり.zshrcなりに追加する。

export MODULEBUILDRC="/usr/local/CPAN/.modulebuildrc"
export PERL_MM_OPT="INSTALL_BASE=/usr/local/CPAN"
export PERL5LIB="/usr/local/CPAN/lib/perl5:/usr/local/CPAN/lib/perl5/x86_64-linux-thread-multi"
export PATH="/usr/local/CPAN/bin:$PATH"

これでセットアップは完了。


mod_perlで動いている既存のシステムから、このlocal::lib環境を使う場合はhttpd.confに以下のように書く。

PerlSwitches -I/usr/local/CPAN/lib/perl5 -I/usr/local/CPAN/lib/perl5/x86_64-linux-thread-multi

VirtualHostを使っている場合は、グローバルなPerlSwitchesを読んでくれないので、内にこう。

PerlOptions +Parent
PerlSwitches -I/usr/local/CPAN/lib/perl5 -I/usr/local/CPAN/lib/perl5/x86_64-linux-thread-multi

Nagiosのcheck_mysqlに.my.cnfを参照させる

MySQLの稼働やレプリケーション監視は柔軟性が欲しくて自前のスクリプトでやっているのですが、それとは別にNagiosでの監視もそれはそれで欲しいよね、という話。

check_mysqlに直接パスワード渡すとかないわー、と思って.my.cnfを渡す方法を探してみた。

$HOMEさえ設定してやれば、check_mysqlが.my.cnfを読み込んでくれるらしい。

で、こういう風に書くと実際のnagiosユーザのホームディレクトリ(/etc/passwdの設定)は関係ないので、好きなところに.my.cnfを配置出来ると。

define command{
    command_name    check_mysql
    command_line    HOME=/home/nagios $USER1$/check_mysql -H $HOSTADDRESS$
}

この例では、/home/nagios/を手動で作って、そこに

[client]
user = replication_user
password = password

みたいな.my.cnfを置いた。

これでわりといい感じに監視出来るようになりました。

gitのhookでメール送るとか

ググればサンプルはたくさん出てくるのだけど、.git/hooks/post-receiveに

#!/bin/sh
TITLE=`git show '--pretty=format:[リポジトリ名] "%s" by %cn #%h'|head -1`
git show | mail -s "$TITLE" メールアドレス

とか書いておく程度でいいかなと思った。ブランチまで含めた運用はもう少し考えたい。

Gitのフックはreceiveとupdateの違いがよく分からなかったんだけど、man githooksするよりも以下が分かりやすかった。

(以下、2010/11/25追記)
その後、updateで以下のようなhookスクリプトを動かすように変更。

#!/bin/sh
REPO="リポジトリ名"
MAILTO="通知先メールアドレス"

REF="$1"
OLD="$2"
NEW="$3"
BR=${REF##refs/heads/}
${BR:="master"}

TITLE=`git show "--pretty=format:[${REPO}:${BR}] \"%s\" by %cn #%h" $NEW|head -1`
git show $NEW | mail -s "$TITLE" $MAILTO