環境変数FACTERLIBについて

#facter

Facterはシステムの状態を収集するツールである。 Puppet関連ツールの1つで、位置づけでいえばChefにとってのOhaiである。 コマンドラインからの実行も可能で、例えば以下のように、osに関する情報を取得することが出来る。

$ facter os
=> {"name"=>"Darwin", "family"=>"Darwin", "release"=>{"major"=>"13", "minor"=>"4", "full"=>"13.4.0"}}

Facterに関する詳細はドキュメント12に譲るとして、今回は環境変数FACTERLIBの話をしたい。

FACTERLIB

Custom Factsを簡単に説明すると、Factsの拡張を自作することである。 そしてそのCustom Factsをコマンドラインから読み取る時に、環境変数FACTERLIBを用いる。 (もう少し正確に書くと、$LOAD_PATHFACTERLIB、そしてPuppetの場合はpluginsync3で配布されたFactsが読み込まれる)

環境変数FACTERLIBの使い方は以下のとおり。

FACTERLIB="/PATH/TO/FACTS" facter your_custom_fact
=> value

Custom Factsのあるディレクトリパスを指定すれば、簡単に呼び出せる。 PuppetでFactsの値を確かめたい時などに活用出来る。

どこで実装されている?

FACTERLIBを使えばCustom Factsを呼び出せることは分かった、ではそれはどのように実現されているのだろう。

lib/facter/util/loader.rb#L70-91に定義されるsearch_pathメソッドに実装を見つけた。 このメソッドに配列search_pathsがあり(メソッド名と紛らわしいが)、どうやらここでパスの収集を行っているらしい。

def search_path
  search_paths = []
  search_paths += $LOAD_PATH.map { |path| File.expand_path('facter', path) }

  if @environment_vars.include?("FACTERLIB")
    search_paths += @environment_vars["FACTERLIB"].split(File::PATH_SEPARATOR)
  end
  ...
end

search_pathsには、まず$LOAD_PATHのそれぞれの末尾にfacterをつなげたものが入る。 そして次に、環境変数FACTERLIBの内容をsplitしてsearch_pathsに追加している。 File::PATH_SEPARATORはパスの区切り文字、デリミタのことで、UNIX環境では:が入る4

search_pathsはどこで使われているかというと、loader.rb#L24-L32loader.rb#L43-L52あたりでpathに含まれるCustom Factsらをloadするのに用いられている。 以下にloader.rb#L43-52を示す。

paths = search_path
unless paths.nil?
  paths.each do |dir|
    # dir is already an absolute path
    Dir.glob(File.join(dir, '*.rb')).each do |path|
      # exclude dirs that end with .rb
      load_file(path) if File.file?(path)
    end
  end
end

Dir.glob(File.join(dir, '*.rb'))とあるように、search_pathsの各パスの中にある*.rbなファイルを全てロードしている。

まとめ

Facterはシステムの情報収集ツールであり、標準機能の他にCustom Factsを使って拡張が可能である。 コマンドラインからCustom Factsを利用したい場合は、環境変数FACTERLIBを指定し、FACTERLIB="/PATH/TO/FACTS" facter your_custom_factのように使えばよい。