summaryrefslogtreecommitdiff
path: root/devdocs/vagrant/plugins%2Fcommands.html
blob: cb46319af6d8e3009f4f9df0be6d8a0f85dd06cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<h1 id="plugin-development-commands">  Plugin Development: Commands </h1> <p>This page documents how to add new commands to Vagrant, invocable via <code>vagrant YOUR-COMMAND</code>. Prior to reading this, you should be familiar with the <a href="development-basics">plugin development basics</a>.</p> <blockquote class="alert alert-warning"> <p><strong>Warning: Advanced Topic!</strong> Developing plugins is an advanced topic that only experienced Vagrant users who are reasonably comfortable with Ruby should approach.</p> </blockquote>
<h2 id="definition-component">  Definition Component </h2> <p>Within the context of a plugin definition, new commands can be defined like so:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">command "foo" do
  require_relative "command"
  Command
end
</pre></div>
<p>Commands are defined with the <code>command</code> method, which takes as an argument the name of the command, in this case "foo." This means the command will be invocable via <code>vagrant foo</code>. Then the block argument returns a class that implements the <code>Vagrant.plugin(2, "command")</code> interface.</p> <p>You can also define <em>non-primary commands</em>. These commands do not show up in the <code>vagrant -h</code> output. They only show up if the user explicitly does a <code>vagrant list-commands</code> which shows the full listing of available commands. This is useful for highly specific commands or plugins that a beginner to Vagrant would not be using anyways. Vagrant itself uses non-primary commands to expose some internal functions, as well.</p> <p>To define a non-primary command:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">command("foo", primary: false) do
  require_relative "command"
  Command
end
</pre></div>
<h2 id="implementation">  Implementation </h2> <p>Implementations of commands should subclass <code>Vagrant.plugin(2, :command)</code>, which is a Vagrant method that will return the proper superclass for a version 2 command. The implementation itself is quite simple, since the class needs to only implement a single method: <code>execute</code>. Example:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">class Command &lt; Vagrant.plugin(2, :command)
  def execute
    puts "Hello!"
    0
  end
end
</pre></div>
<p>The <code>execute</code> method is called when the command is invoked, and it should return the exit status (0 for success, anything else for error).</p> <p>This is a command at its simplest form. Of course, the command superclass gives you access to the Vagrant environment and provides some helpers to do common tasks such as command line parsing.</p> <h2 id="parsing-command-line-options">  Parsing Command-Line Options </h2> <p>The <code>parse_options</code> method is available which will parse the command line for you. It takes an <a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/OptionParser.html">OptionParser</a> as an argument, and adds some common elements to it such as the <code>--help</code> flag, automatically showing help if requested. View the API docs directly for more information.</p> <p>This is recommended over raw parsing/manipulation of command line flags. The following is an example of parsing command line flags pulled directly from the built-in Vagrant <code>destroy</code> command:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">options = {}
options[:force] = false

opts = OptionParser.new do |o|
  o.banner = "Usage: vagrant destroy [vm-name]"
  o.separator ""

  o.on("-f", "--force", "Destroy without confirmation.") do |f|
    options[:force] = f
  end
end

# Parse the options
argv = parse_options(opts)
</pre></div>
<h2 id="using-vagrant-machines">  Using Vagrant Machines </h2> <p>The <code>with_target_vms</code> method is a helper that helps you interact with the machines that Vagrant manages in a standard Vagrant way. This method automatically does the right thing in the case of multi-machine environments, handling target machines on the command line (<code>vagrant foo my-vm</code>), etc. If you need to do any manipulation of a Vagrant machine, including SSH access, this helper should be used.</p> <p>An example of using the helper, again pulled directly from the built-in <code>destroy</code> command:</p> <div class="highlight"><pre class="highlight ruby" data-language="ruby">with_target_vms(argv, reverse: true) do |machine|
  machine.action(:destroy)
end
</pre></div>
<p>In this case, it asks for the machines in reverse order and calls the destroy action on each of them. If a user says <code>vagrant destroy foo</code>, then the helper automatically only yields the <code>foo</code> machine. If no parameter is given and it is a multi-machine environment, every machine in the environment is yielded, and so on. It just does the right thing.</p> <h2 id="using-the-raw-vagrant-environment">  Using the Raw Vagrant Environment </h2> <p>The raw loaded <code>Vagrant::Environment</code> object is available with the '@env' instance variable.</p><div class="_attribution">
  <p class="_attribution-p">
    &copy; 2010&ndash;2018 Mitchell Hashimoto<br>Licensed under the MPL 2.0 License.<br>
    <a href="https://www.vagrantup.com/docs/plugins/commands.html" class="_attribution-link">https://www.vagrantup.com/docs/plugins/commands.html</a>
  </p>
</div>