Skip to content
This repository was archived by the owner on Nov 9, 2020. It is now read-only.

Writing New Commands

rlane edited this page Apr 4, 2011 · 5 revisions

RVC is designed to make adding your own commands easy. Most commands will need to use the RbVmomi library; see its documentation.

Command Modules

Every command exists in a module, which is just a Ruby file in a special directory. The default directories searched are lib/rvc/modules in the source tree and ~/.rvc. You can add other directories by including them in the environment variable RVC_MODULE_PATH, separated by colons. The module will be named the same as the Ruby file, minus the .rb extension. If you have files with the same name in different module directories they will be combined into the same module.

For rapid development, you can reload command modules while RVC is running. Just use the reload command. It will also tell you the location of each command module it loads.

Example

This example is taken from the vm module. Copy it into ~/.rvc/test.rb (you may need to create the directory first).

opts :remove_device do
  summary "Remove a virtual device"
  arg :vm, nil, :lookup => VIM::VirtualMachine
  arg :label, "Device label"
end

def remove_device vm, label
  dev = vm.config.hardware.device.find { |x| x.deviceInfo.label == label }
  err "no such device" unless dev
  spec = {
    :deviceChange => [
      { :operation => :remove, :device => dev },
    ]
  }
  vm.ReconfigVM_Task(:spec => spec).wait_for_completion
end

Now restart RVC or use the reload command. You should be able to use the test.remove_device command.

Option parsing

Every command has its own command line option parser, defined by the opts method. This parser is based on Trollop with a few additions.

The summary method is used to define the text to show in the help listing.

opt has a new option: :lookup. If this is set to a class then RVC will treat the value given by the user as a path and look it up in the virtual filesystem. If it isn't found, or if it does not match the class given to :lookup, then RVC will display an error message and not execute the command. If it was found, the object will be given to the command instead of the path string.

The biggest addition is the arg method. This defines a positional argument. The first parameter is the name, which is used only for documentation, and the second parameter is an optional description. arg supports the :default, :multi, :required, and :lookup options just like opt. In this case, :multi means that all remaining positional parameters are consumed, so it must be the last call to arg.

The command method should accept one argument for each positional argument. Positional arguments with the :multi option will be given as an array. If there are any options defined, the command will need to accept a hash as its last argument.

Utility methods

See the implementations in lib/rvc/util.rb for more information.

  • lookup(path) - Look up a path in the virtual filesystem and return the object found, or nil if it didn't exist.
  • lookup!(path,class) - Same as lookup, but raises an exception if the object doesn't exist or doesn't match the given class.
  • err(message) - Throw an exception that will be displayed without a backtrace.
  • progress(tasks) - Wait for all the given tasks to complete or fail, displaying progress bars.
  • tasks(objs, sym, args) - Call a Task-returning method sym (without the _Task suffix) on each object in objs with an option hash. The returned tasks are passed to the progress function.
  • system_fg(cmd) - Execute cmd in a new foreground process group.

Clone this wiki locally