若者がパッケージ管理について思うことの今の結論

先日エントリを書いたら、各方面から「長い」「タイトルが意味不明」「若いっていいよね」とたくさんの dis を頂きありがとうございました。

そういえば、長くなりすぎて今のところの自分の結論書くのも忘れてたので、頂いたアドバイスも交えてもうちょっと書きます。

結論:あるサーバの正しい状態が定義できれば管理方法は問わない

というわけで、パッケージ管理と呼んでいるものの外側から、ともかく正しい状態というのを何かしら定義することができれば、別にパッケージ管理の手法は問わないし何種類も組み合わせていいと思ってます。Touryo という自作のツールはそういう思想も受け入れていて、一部そういう管理を試しているところです。

抽象的で分かりにくいのでもうちょっと具体化すると、例えば rpm でのライブラリのパッケージ管理と cpan による perl モジュールのパッケージ管理は、XS などがある場合に完全に直交できないのは先のエントリで書いた通りですが、両方の正しい状態(入っているべきパッケージ名とバージョンの組み合わせ)が何かしら定義できていれば、それに従ってインストールすれば確実に同じものができあがるわけです。

このように、パッケージ管理が複数絡みあう場面でも、パッケージ管理のパッケージ名とバージョンという特徴をうまく利用すると管理は可能です。メタパッケージ管理というか。まぁ場合によってはインストールの順番とかでできるものが変わったりするようなヘンテコなパターンも考えられると思いますが、ならインストールの順番も含めて管理すればいいかなと。

以下、理由とか。

1 つの管理方法で管理するのは無理

kazuho さんも「両者は競合しないように機能分割すればいい」と仰っている様に、別に管理が複数あっていいと思います。むしろ、先のエントリでちょっと例を出したように OS レベルで入れる様なライブラリを LL の様な世界に管理させようとすると各言語ごとに Alien::Hogehoge みたいなものを作らないといけなくて、それこそ管理できなくなっちゃいます。

LL ごとや LL のパッケージごとに、ライブラリのバージョンを変えたいとかになってくるとかなり複雑なパターンなので難しくなってきますが、上で書いたメタ管理の様な仕組みを作っておけば、そっちを複雑にすることでなんとか対応出来ると思います。例えばある LL 用にだけ別バージョンのライブラリを名前をかえたパッケージでインストールするとか。

管理をしない管理も 1 つの手

ひろせせんせいが書かれている方法は先に述べたやり方と真っ向から対抗するやり方です。パッケージ管理を敢えてせず、あるサーバを元にファイルコピーで作っていく方法は、敢えて管理をしない管理方法で、1 つの答えだと思います。

前提として上げられている通り、OS やアーキテクチャを揃えることが現実的であれば、このやり方は十分に通用すると思います。しかし世の中そううまくいかないことも多く、僕はまさにそれに苦しめられてたりします。

そういう場面においては、パッケージ管理を活用するのは便利なやり方です。(擬似)クロスコンパイル的にやって OS/アーキテクチャ毎に必要なファイルを配置してあくまでファイルコピーにこだわってもいいのですが、結構面倒です。llenv は一応そういう発想で作ってはみたんですが、現実的にはイマイチ使えないなぁと思ってるところ。

なので、冒頭に書いた様にパッケージ管理のパッケージ名とバージョンを使って正しい状態を指定する方が管理は簡単になります。OS/アーキテクチャの種類ごとに色々作らないといけないのは面倒ですが、それはどういう方法をとっても発生してしまいますし。

中途半端にパッケージ管理させない

cpanmコマンドなどでは依存関係をたどってインストールとかyumコマンドだと groupinstall という仕組みがあったりとかあるわけですが、そういう中途半端な管理はさせない方がいいと思ってます。何故なら意図せぬモジュールが入ったり、インストールのタイミングによってバージョンが変わってしまったりするからです。

そういうことはパッケージ名とバージョンを外側から管理することで回避できます(さらに言えばそのパッケージ自体も自分で管理)。最近ほとんどの LL では perl でいう carton、ruby でいう bundle の様にそういうことをやれるパッケージ管理が主流になりつつあります。こういった管理方法は優れているので、積極的に管理に使っていくと良いと思います。yum であればローカルに自分たち用のレポジトリを立てて、変にバージョンが上がってしまうことを防ぎつつ、入れるべき rpm のリストは group とかとは別でrpm -qa --qf '%{name}-%{version}-%{release}.%{arch}\n'を管理するイメージです。

パッケージ管理は広い

ここまでパッケージ管理として述べてきた内容には、意図的ではありますが色んなレイヤーの話題が含まれてます。アプリのデプロイに関する管理もあれば、サーバ自体の構成情報の管理もあります。先のエントリでは敢えてそれらを広義にパッケージ管理としてひとつにとらえて共通性を見出してみたわけですが、現実的には色々と違いがあります。

なのでそれぞれの目的に応じて適切なパッケージ管理を使いつつ、OS 単位ではどういう状態が正しい状態なのかを定義してあげてそれを管理するというやり方が最も現実的だと考えています。

まとめ

いいなと思ってるのはこんな感じ。

  • パッケージ管理達を外側からメタ管理する

    • パッケージ名とバージョンの一覧を管理
    • 複数の管理方法を両立できる
  • あるサーバの正しい状態を定義する

    • 正しい状態をキープする
  • パッケージ自体を含めて管理する

    • いつも外部レポジトリからダウンロードするのでなく、ローカルに持つ

またきっと厳しいツッコミ受けると思いますが、とりあえずこんなところでー><