その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

CentOS 6.6 上で NVIDIA の GPU (の一部) と共に nouveau 使うと発狂して死ぬ

タイトルの通りです.
CentOS 6.6 の上で NVIDIAGPU の一部のモデルを nouveau と一緒に使うとカーネルパニックを起こして死にます.OS が起動しねえ.
一部というのは確認できた限り

  • GTX 690
  • GTX 590
  • GTX Titan
  • Tesla K20Xm

です.Quadro 系はなぜか大丈夫でした.環境に依る気がする.GeForce 系は軒並み死ぬのではないかと思います.


他の CentOSディストリビューションについては調べてませんがまあ死ぬと思います.
ついでに言うと Ubuntu でも死にます.勘弁してくれ.

解決

nouveau がいくら自由な存在とてカーネルパニック起こしてクラッシュするのはどうしようもないので
NVIDIAプロプライエタリドライバをインストールすることにします.

とにかく OS が起動しないとどうにもならんので OS を起動させます.
オンボードのグラフィック機構で起動させるか,クラッシュしない GPU を挿して起動します.


起動したらおもむろに RunLevel を 3 に変更します (もともと 3 ならしなくても良い).

$ sudoedit /etc/inittab
id:3:initdefault:


ついでに nouveau を無効にします.これをやっておかないと NVIDIAプロプライエタリドライバがインストール出来なくてキレる羽目になるので.

$ sudoedit /boot/grub/grub.conf
(略)
KEYTABLE=us rd_NO_DM rhgb quiet nouveau.modeset=0
#                               ~~~~~~~~~~~~~~~~~ 対象の kernel のオプションにこれを書く


ここで併せて NVIDIA のドライバのインストーラをダウンロードして然るべき場所に置いておきましょう.
そしてリブート.


リブートしたらドライバのインストーラを起動して,あとは適当にインストールしてゆきます.
インストールが終わったら RunLevel を 5 に戻す (もともと 3 ならそのままで良い).

$ sudoedit /etc/inittab
id:5:initdefault:


そしてリブートすると直っているという感じです.タイミングで適宜所望の GPU に挿し換えておきましょう.
最初原因わからなくて困った.

Java で新しくプロジェクトを始めるときに何を使ってセットアップすべきか

Java で新しいプロジェクトを立ち上げる時,

という2つの方法が考えられると思います (他にもあるかも知れない).
さてどちらが良いのか.

Maven Archetype を使う

利点
  • mvn さえマシンに入っていれば OK (他の処理系がいらない)
  • Maven Central (社内に立ってるようなミラーを含む) に archetype が上がっていると明示的なインストール等が無く使えるので便利
    • 配布が楽!!!!!!
    • 簡単に使える
      • アップロードされている場合,以下のようにするとセットアップできる
mvn archetype:generate -DarchetypeGroupId=com.example -DarchetypeArtifactId=sample-archetype -DarchetypeVersion=1.0.0
欠点
  • Archetype 作るのは色々とだるい (独自のルールとか.まあこれは仕方がないので慣れるしか無い,何回かやると慣れる)
  • 凝ったこと (例えば,コマンドライン引数に応じてファイルの出しわけをするとか) をしようとすると詰む
  • 処理が重い (諦める)

セットアップスクリプトを使う

利点
  • 自由度が高い
    • 例えば上に書いたコマンドライン引数に応じてファイルの出しわけをする (--adminオプションを付けると,管理画面用の雛形が追加されるみたいな) とかが簡単に実現できる
  • ルールに縛られず自分の好きなように作れるので作りやすい
欠点
  • 実行に際して別途セットアップスクリプトの為の処理系が必要
  • 配布が面倒くさい
    • セットアップスクリプトをどこに置くか
    • どうやってインストールするのか
    • 簡単に使えるのか

所感

とりあえず通常の場合は Maven Archetype を使っていくのが良いような気がします.
Java のプロジェクトをやろう!」という人のマシンには間違いなく mvn は入っているでしょうし,なにより archetype配布や実行が楽だからです.Maven Archetype は凝ったことをしない限り戦っていくことが可能です.
配布や実行が楽というのは本当に重要であります.この辺が面倒くさいと誰も使わないし,保守するモチベーションも死んでゆくし,その結果いくら良い雛形であっても滅亡してゆきます.ので,ここは本当に重要.
処理が重いというのはありますが,絶望的に重いわけではないのでここらへんは割り切っていきましょう.そんな頻繁に叩くものでもないので.


Maven Archetype では無理だ!」というレベルの凝ったことをしたくなった時には独自のセットアップスクリプトを用意するくらいで良いという意識になっています.
この場合,セットアップスクリプトをどこに置くかという問題はありますが,そのあたりは GitHub Releases とか,Jenkins の成果物とか,まあいくらでもやりようはあるのかなと思っています.
(雑考: ここらへんに golang を使っていくというアプローチはどうか.ビルド済みのバイナリを然るべき場にソイヤしておくと,各位が適宜エイヤできる気がする)


archetype の作成はだるい,というのはまああるにはあるんですが,セットアップスクリプトを作る場合も結局は面倒なので,この辺は支配的な差にはならないように感じています.


Maven Archetype,最初はその風貌や名前からウッアッという感じになるんですが,慣れると何とかなります.
ひとまずこれで良いんじゃないですかね.

Maven Archetype で文字列を置換したりする

Maven Archetypearchetype を作るとき,文字列を置換したくなることがあります.
例えば $artifactIdfoo-bar と入っている時にこれを foo_bar という風に s/-/_/g したくなる事などがあるでしょう.世の中色々あるのです.

そういう時は以下のように書いてやると良い.

${artifactId.replaceAll("-", "_")}

こういう感じで普通に replaceAll() 等の String のインスタンスメソッドを呼び出すことが出来るので便利.


でもって pom.xml

#set($replaced = $artifactId.replaceAll("-", "_"))

とか書いてやると,archetype 内で $replaced という変数が置換後の内容として使えるようになるので便利!!


現場からは以上です.

Maven Archetype で ## がコメントとして扱われるのでなんとかする

Maven Archetypearchetype を作る時,archetype に含めるファイルの中に ## が入っていると行のそれ以降がコメントとして扱われる為,内容が抜け落ちてしまうというような事があります.
例えば Markdown 形式のファイルなんかを archetype 内に含めていると悲惨で,

## My Awesome Project!

という風に,見出しを期待して ## から始める文を書いてしまうと,これはコメントとして扱われ空行として出力されることになります.
これはMaven Archetype が内部で使っている Apache Velocity が ## をコメントとして扱う為です.ジーザス.


こうした時にどうやって archetype 中のファイルで ## を使うのか,という話ですけれども,archetype-resources/pom.xml の先頭に #set($sharp = '#') と書いてやるとよろしい.


例;

#set($sharp = '#')
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
</project>

こうすると,$sharp という変数が # として扱われるようになります.
そして ## が含まれるファイルはこのように書き換える;

${sharp}${sharp} My Awesome Project!


見た目は悪いがコイツは動く.

YAPC::Europe 2015 にて “Static Code Analysis For Perl” というタイトルで発表します

2015年9月2日から4日までスペインはグラナダで開催される YAPC::Europe 2015 にて,
“Static Code Analysis For Perl” というタイトルで発表することになりました.実は通ると思ってなかった!!


YAPC::Europe 2015 | Static Code Analysis For Perl


例にもよって Perl の静的解析の話とか,ぶっちゃけ Perl::Lint の話になると思います.Perl::Lint はそろそろ完成の目処が立ってきているので…… *1
海外のカンファレンスで英語で話すのは一昨年のウィーン以来なので緊張しますね!


成田からの所要時間はおおよそ15時間とのことで,なんと1日かかりません.お手軽ですね.
皆さん是非現地でお会いしましょう.


ところで YAPC::Europe 2015 のトーク応募はまだ受付中のようなので,どんどん応募されると良いのでは無いかと思います.

*1:要出典

相手の GitHub の ID さえ知っていれば暗号化したメッセージを送れる naisho というのを作った

色々な事情があり,秘密のメッセージを送り合う必要性が今年に入ってから多数発生していて,
そのたびに毎度毎度手で暗号化して〜みたいな風にやるのめんどいですね,そうですね,
ということでこの度 naisho というものをこさえました.みんなには内緒ですよ.


これは何かと言うと,やりとりしたい相手の GitHub の ID を指定するだけで

  • その ID のユーザの ssh-rsa の公開鍵を引っ張ってきて
  • その ID のユーザのメールアドレスを引っ張ってきて
  • そのメールアドレスに対して公開鍵で暗号化したメッセージを添付ファイルにしてメールで送りつける

という動きをするコマンドです.
golang で書きたかったというのと golang で書くと便利なのではと思ったので golang で書いてあります.


Wercker で Go のプロジェクトをクロスコンパイルし、GitHub にリリースする - 詩と創作・思索のひろばや,
werckerでgithubにreleaseをdeployするまでの道のり - yuukichiの日記
を参考にすることで、wercker でバイナリをビルドして GitHub Releases に成果物を設置するということも出来ました.
Releases · moznion/naisho · GitHub からお手軽に入手頂けます.


さて使い方としては

$ naisho <Target GitHub ID> <Message>

としてやるだけで,対象の GitHub ID のユーザーに暗号化した Message を添付ファイルにしてメールで送りつける事ができます.
受け取った側は openssl さえ持っていれば良くて,

$ openssl rsautl -decrypt -inkey <Your Secret Key> -in <Attachment>

という感じで,公開鍵と対応している秘密鍵と添付ファイルを指定してやるだけで内容を読むことが出来ます.


中身の仕組みですが,GitHubhttps://github.com/<user-id>.key という所にアクセスすると,
任意のユーザの ssh-rsa 公開鍵の一覧を引っ張ってこれるという機能があるので *1
ここから一番上の公開鍵を引っ張ってきてそれで暗号化しています.
送信先メールアドレスはプロフィールページ (つまりhttps://github.com/<user-id>) に書いてあるメールアドレスを
GitHub API 経由で取得してくることができるのでそれで取ってきています.
従って,当然ですが公開鍵を登録していないユーザや,メールアドレスを公開していないユーザには送ることが出来ません.残念!


使う鍵の鍵長によって暗号化出来るバイト数が変わってきて,

鍵長ビット 暗号化可能バイト
1024bit 117byte
2048bit 246byte
4096bit 502byte
8192bit 1018byte

という感じなので,そこまで長いメッセージは送れないという世界観です (バイト数が溢れると暗号化に際してエラーが出る).

しかしこれは十分な長さです! これで私にクレジットカードの番号や WebMoney のコード等を安全に送り放題ですね!! やりました!!!


今後の予定としてはファイル入力を受け付けられたり,使う公開鍵をインタラクティブに選べたりできたら良いなあとぼんやり思っています.あとエラーメッセージが雑極まりないので直したいですね!
ご利用くださいませ.

*1:ゆくゆくは無くなるらしい……

git でファイルごとのコミット数を取ってきて,プロジェクト中のホットなファイルを割り出すという試み

途中の段階でプロジェクトに入った時などに,「どれがそのプロジェクトの中心となっているファイルなんだろうか」というのを手っ取り早く知りたくなる時があります.僕はあります.


そこで「どのファイルが盛んに変更されているのか」という点を指標として注目すると,良い感じにそこら辺取れるのでは無いかと思って試してみました.
コミット数が多いファイルは多く変更を加えられているということから,そうしたファイルはホットであるということが言えそうな気がしたので,git でファイルごとのコミット数を取ってきて,それをソートして見てやれば良いよな,という意識でやっていきました.もちろんコミットの粒度などもあるでしょうから一概にはそうとは言い切れませんが,参考にはなる気はします.


使うスクリプトは至って簡単.以下の様な感じです.

git ls-files |
while read file ; do
  commits=`git log --oneline -- $file | wc -l`;
  echo "$commits - $file";
done | sort -n

git で管理されているディレクトリ内でこのシェルスクリプトを走らせるとそのような情報を取ってくることが出来ます.
railsリポジトリで試してみました所,以下の様な結果が得られました.

1 - actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb
1 - actionmailer/test/fixtures/anonymous/welcome.erb
1 - actionmailer/test/fixtures/another.path/base_mailer/welcome.erb
1 - actionmailer/test/fixtures/asset_host_mailer/email_with_asset.html.erb
1 - actionmailer/test/fixtures/asset_mailer/welcome.html.erb
<中略>
549 - activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
556 - actionpack/CHANGELOG.md
745 - activerecord/lib/active_record/associations.rb
1134 - activerecord/CHANGELOG.md
1145 - activerecord/lib/active_record/base.rb

なるほどという感じです.正しいのかどうかはよくわかりません.rails 識者の方どうでしょうか.
めっちゃコミット数あった (5万コミットくらい) ので実行に15分くらいかかって大変微妙な心境になります.


よくわからなかったので,なんとなくわかるであろう Plackリポジトリで試してみます.

1 - eg/dot-psgi/Dumper.psgi
1 - eg/dot-psgi/echo-stream-sync.psgi
1 - eg/dot-psgi/runnable.psgi
1 - eg/dot-psgi/static/index.html
1 - eg/dot-psgi/static/test.js
<中略>
113 - Makefile.PL
150 - lib/Plack/Response.pm
178 - Changes
197 - lib/Plack.pm
211 - lib/Plack/Request.pm

なるほど,それっぽい感じがしますね!! (こっちはすぐ実行し終わった)


という感じでまあまあ参考になる情報が取れるのではないでしょうか,という気持ちです.試しに色々なリポジトリに適用していってますが,それっぽい結果が得られてて面白いですね.
逆にコミット数が少ないファイルはメンテされてないから危険,みたいなのも分かるんでしょうか.要検討という感じです.
グラフ等で可視化してやるとまた面白さが出てくるかもしれませんね.

参考


[追記]
歴史が深いリポジトリでやるとめちゃめちゃ時間がかかって大変なので,トラックする log の数を制限するとかが必要になってくるかもわかりませんね.
あと「昔はホットだったけど最近はホットではない」みたいなのもあると思うので,常にすべてのコミット履歴を追う必要は無くて,ある一定のところでバチッと切ってしまうとか,そういうのも考えていく必要があるのかな~とか思った次第です.

こんな風に (この例では -1000 で制限をかけている).

git ls-files |
while read file ; do
  commits=`git log -1000 --oneline -- $file | wc -l`;
  echo "$commits - $file";
done | sort -n

[追記]
log の数に制限かけても処理時間そんな変わらないので,ファイル数の問題であることが伺えます.厳しい……
とは言え「昔はホットだったけど最近はホットではない」みたいなのには関係してきそうなので検討する価値はありそう.

間違っているので見なかったことにしましょう