LoginSignup
5
4

More than 5 years have passed since last update.

Vagrantのpluginを自作した時の雑多なメモ

Posted at

現在の仮想マシンの設定情報をvagrantから入手したい。
こんな感じ。フォーマットはjsonとかが理想形。

vagrant info 

CPU:...
Mem:...
...
...

まともにVagrantファイルをパースするのは馬鹿らしい。
Rubyのインタプリタを書いても仕方がないのでvagrantに手を入れることにする。

vagrantの既存コマンドがどう動作してるのか

とりあえず、`vagrant upコマンドなどを編集して動作確認してみると、
適当な変数をダンプしてみるといろいろ情報が取れそうなことが分かった。

自作コマンドを追加したい

目的を達成するためにvagrantを修正してvagrant infoコマンドを自作して追加することを考える。

ソースを見ていると実行できるコマンドのリストは

# cli.rb
Vagrant.plugin("2").manager.commands

でも、ソース見ててもCommandUpがどこから登録されているのか不明。

# lib/vagrant/plugin/v2/manager.rb

        # This registers a plugin. This should _NEVER_ be called by the public
        # and should only be called from within Vagrant. Vagrant will
        # automatically register V2 plugins when a name is set on the
        # plugin.
        def register(plugin)
          if !@registered.include?(plugin)
            @logger.info("Registered plugin: #{plugin.name}")
            @registered << plugin
          end
        end

で、登録されている。
いろいろ調べていくと、以下の箇所でプラグインのロードが行われて追加されるようだ。

# vagrant.rb

# A lambda that knows how to load plugins from a single directory.
plugin_load_proc = lambda do |directory|
  # We only care about directories
  next false if !directory.directory?

  # If there is a plugin file in the top-level directory, then load
  # that up.
  plugin_file = directory.join("plugin.rb")
  if plugin_file.file?
    global_logger.debug("Loading core plugin: #{plugin_file}")
    load(plugin_file)
    next true
  end
end

# Go through the `plugins` directory and attempt to load any plugins. The
# plugins are allowed to be in a directory in `plugins` or at most one
# directory deep within the plugins directory. So a plugin can be at
# `plugins/foo` or also at `plugins/foo/bar`, but no deeper.
Vagrant.source_root.join("plugins").children(true).each do |directory|
  # Ignore non-directories
  next if !directory.directory?

  # Load from this directory, and exit if we successfully loaded a plugin
  next if plugin_load_proc.call(directory)

  # Otherwise, attempt to load from sub-directories
  directory.children(true).each(&plugin_load_proc)
end

起動時に、ソースのplugin以下を再帰的に調べて行ってplugin.rbファイルがプラグインとして追加される。

つまりここまで調べてわかったのは、新しいコマンドを追加したい場合にはvagrantのpluginを作成し追加するだけで
よさそうであるということである。

plugin作ってみた

早速目的を達するために自分でpluginを作ることにした。

vagrant statusのソースを読んでいくと

with_target_vms(argv)

から各種VMの情報を取得していたので、この変数から情報をそのままJSONに変換して出力するような
プラグインを作ってみた。

vagrant-info

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4