116 lines
3.6 KiB
Markdown
116 lines
3.6 KiB
Markdown
|
---
|
||
|
sidebar_current: "plugins-commands"
|
||
|
---
|
||
|
|
||
|
# Plugin Development: Commands
|
||
|
|
||
|
This page documents how to add new commands to Vagrant, invokable
|
||
|
via `vagrant YOUR-COMMAND`. Prior to reading this, you should be familiar
|
||
|
with the [plugin development basics](/v2/plugins/development-basics.html).
|
||
|
|
||
|
<div class="alert alert-warn">
|
||
|
<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>
|
||
|
</div>
|
||
|
|
||
|
## Definition Component
|
||
|
|
||
|
Within the context of a plugin definition, new commands can be defined
|
||
|
like so:
|
||
|
|
||
|
```ruby
|
||
|
command "foo" do
|
||
|
require_relative "command"
|
||
|
Command
|
||
|
end
|
||
|
```
|
||
|
|
||
|
Commands are defined with the `command` method, which takes as an argument
|
||
|
the name of the command, in this case "foo." This means the command will be
|
||
|
invokable via `vagrant foo`. Then the block argument returns a class that
|
||
|
implements the `Vagrant.plugin(2, :command)` interface.
|
||
|
|
||
|
## Implementation
|
||
|
|
||
|
Implementations of commands should subclass `Vagrant.plugin(2, :command)`,
|
||
|
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: `execute`. Example:
|
||
|
|
||
|
```ruby
|
||
|
class Command < Vagrant.plugin(2, :command)
|
||
|
def execute
|
||
|
puts "Hello!"
|
||
|
0
|
||
|
end
|
||
|
end
|
||
|
```
|
||
|
|
||
|
The `execute` method is called when the command is invoked, and it should
|
||
|
return the exit status (0 for success, anything else for error).
|
||
|
|
||
|
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.
|
||
|
|
||
|
## Parsing Command-Line Options
|
||
|
|
||
|
The `parse_options` method is available which will parse the command line
|
||
|
for you. It takes an [OptionParser](http://ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/OptionParser.html)
|
||
|
as an argument, and adds some common elements to it such as the `--help` flag,
|
||
|
automatically showing help if requested. View the API docs directly for more
|
||
|
information.
|
||
|
|
||
|
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 `destroy` command:
|
||
|
|
||
|
```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)
|
||
|
```
|
||
|
|
||
|
## Using Vagrant Machines
|
||
|
|
||
|
The `with_target_vms` 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 (`vagrant foo my-vm`), etc.
|
||
|
If you need to do any manipulation of a Vagrant machine, including SSH
|
||
|
access, this helper should be used.
|
||
|
|
||
|
An example of using the helper, again pulled directly from the built-in
|
||
|
`destroy` command:
|
||
|
|
||
|
```ruby
|
||
|
with_target_vms(argv, :reverse => true) do |machine|
|
||
|
machine.action(:destroy)
|
||
|
end
|
||
|
```
|
||
|
|
||
|
In this case, it asks for the machines in reverse order and calls the
|
||
|
destroy action on each of them. If a user says `vagrant destroy foo`, then
|
||
|
the helper automatically only yields the `foo` 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.
|
||
|
|
||
|
## Using the Raw Vagrant Environment
|
||
|
|
||
|
The raw loaded `Vagrant::Environment` object is available with the
|
||
|
'@env' instance variable.
|