VM で複数の Linux を動かしている。設定はほぼ同じなのだが、「ほぼ」が難しい

この項は順次追記していく

環境

VM で Linux が幾つかある。もちろん同じ物では無い。ディストリビューションが 違ったり、特定のアプリケーションを使うのが目的だったり。あるいは Linux 以外の OS を動かしたり。

ただ、通常使うアプリケーションは大体決まっている。シェルやエディタなんかは むしろ、環境が変わっても同じ設定にしておかないと使いにくい。

これらに関わる設定ファイルを集中管理することにした。 そうすることで、個々のホストでの変更の取り込み、他のホストへの反映が 簡単になる。

方針

  • 設定ファイルの管理に分散管理を使う
  • 分散管理を使うのだが、1 個を中央(親)とし、他(子)の変更をここに集約する
  • 共通のファイルは、共通置き場に、ホスト毎のファイルは固有ディレクトリに置く
  • ホームは以下の設定ファイルはリポジトリ内へシンボリックリンクを張る事で、どのホストでも同じパス/ファイル名でアクセスできるようにする
  • 環境の識別とインストールはスクリプトを作成し、手間を最小にする
  • ホスト間の通信は ssh で行う(TeraTerm 接続用に既存なので特に作業は無い)

分散管理

検討した結果、Mercurial を使う事にした。

分散管理としては Git が有名であり、同じ事はできると思われるが、 Mercurial の方に慣れている事と、検索で手順が見つかりやすかった ため。

Git だと、単純に既存リポジトリを元にする方法(今回の方式)と最初から 共用リポジトリとして作成して共有する方法(bareリポジトリ)がある。 これはこれで使うべき場面がある。

どちらにしろ、考え方は共通。作業ディレクトリとリポジトリを分けて考える 必要がある点も同様。

手順(最初の作業)

各ホストにリポジトリと作業ディレクトリを用意する。

親ホストを hostA とする。 作業ディレクトリを conf_directory とする。

親ホストでリポジトリを作成する

一通りのファイル群が作成済みとする。

$ cd conf_directory
$ hg init
$ hg add *
$ hg commit -m "メッセージ"

ディレクトリ配下の全ファイルを親リポジトリに取り込む。

子ホストで親ホストのリポジトリを複製する

親リポジトリの複製を取得する

$ hg clone ssh://hostA/conf_directory
$ cd conf_directory

conf_directory ディレクトリが作成されるので、中に降りて作業する。

必要ならユーザ名、ssh ポートを指定する

$ hg clone ssh://user@hostA:port/conf_directory

手順(日常の作業)

子ホストで親ホストの更新を取り込む

他の子ホストでの変更が親ホストへ更新されていることも多くなるはず。 なので、作業の最初に同期する必要が出てくる。

子リポジトリを更新し、作業ディレクトリへ反映する

$ hg pull default
$ hg update

pull に -u オプションをつけると両方を一度に行える。

$ hg pull -u default

子ホストで作業ディレクトリを更新し親ホストに反映する

conf_directory ディレクトリ中で作業(ファイル更新)し、 作業ディレクトリが更新された状態。

作業ディレクトリを子リポジトリへ反映する

$ hg commit -m "メッセージ"

子リポジトリを親リポジトリへ反映する

$ hg push default

親ホストで子ホストの更新を取り込む

子ホストから更新済みの差分をマージする。

前項の作業で親リポジトリに差分は取り込まれたが作業ディレクトリは 更新されていない。

注:diff を取っても出てこない。作業ディレクトリの元となった履歴と 他ホストから追加された履歴が別に(ブランチとして)区別されるためらしい。

$ hg merge

衝突があると手作業が必要になったりする。

内容を確認したら親リポジトリへ反映する

$ hg commit -m "メッセージ"

環境の識別

コマンド、設定ファイルで環境を識別する。 使える情報として以下(その他も)がある。 これらを適宜、組み合わせて識別する。

  • /etc/machine-id ファイル
  • /etc/debian_version ファイル
  • uname コマンド

OS 、ディストリビューション、さらにバージョンによって使えるものが違う。

識別された環境の ID となる文字列を表示する。 または終了コードを返す。

環境設定スクリプト

ホーム配下の設定ファイルはリポジトリへのシンボリックリンクとし、 同一のパス/ファイル名でアクセスできる様にする。 リンク先は共通、またはホスト固有ディレクトリのどちらかになる。

この、ホスト毎に共通/ホスト固有のどちらへリンクを 張るかの作業をスクリプト化し、自動化する。

環境の識別に前項のスクリプトを使う。