lib/chef_metal/driver.rb in clc-fork-chef-metal-0.14.alpha.3 vs lib/chef_metal/driver.rb in clc-fork-chef-metal-0.14.alpha.4
- old
+ new
@@ -4,29 +4,27 @@
# and contains methods to create, delete, start, stop, and find them.
#
# For AWS, a Driver instance corresponds to a single account.
# For Vagrant, it is a directory where VM files are found.
#
- # == How to Make a Driver
+ # = How to Make a Driver
#
# To implement a Driver, you must implement the following methods:
#
- # - initialize(driver_url) - create a new driver with the given URL
- # - driver_url - a URL representing everything unique about your driver.
- # But NOT credentials.
- # - allocate_machine - ask the driver to allocate a machine to you.
- # - ready_machine - get the machine "ready" - wait for it to be booted and
- # accessible (for example, accessible via SSH transport).
- # - stop_machine - stop the machine.
- # - destroy_machine - delete the machine.
- # - connect_to_machine - connect to the given machine.
+ # * initialize(driver_url) - create a new driver with the given URL
+ # * driver_url - a URL representing everything unique about your driver. (NOT credentials)
+ # * allocate_machine - ask the driver to allocate a machine to you.
+ # * ready_machine - get the machine "ready" - wait for it to be booted and accessible (for example, accessible via SSH transport).
+ # * stop_machine - stop the machine.
+ # * destroy_machine - delete the machine.
+ # * connect_to_machine - connect to the given machine.
#
# Optionally, you can also implement:
- # - allocate_machines - allocate an entire group of machines.
- # - ready_machines - get a group of machines warm and booted.
- # - stop_machines - stop a group of machines.
- # - destroy_machines - delete a group of machines.
+ # * allocate_machines - allocate an entire group of machines.
+ # * ready_machines - get a group of machines warm and booted.
+ # * stop_machines - stop a group of machines.
+ # * destroy_machines - delete a group of machines.
#
# Additionally, you must create a file named `chef_metal/driver_init/<scheme>.rb`,
# where <scheme> is the name of the scheme you chose for your driver_url. This
# file, when required, must call ChefMetal.add_registered_driver(<scheme>, <class>).
# The given <class>.from_url(url, config) will be called with a driver_url and
@@ -37,12 +35,12 @@
#
class Driver
#
# Inflate a driver from a driver URL.
#
- # == Parameters
- # driver_url - the URL to inflate the driver
+ #
+ # @param [String] driver_url the URL to inflate the driver
# config - a configuration hash. See "config" for a list of known keys.
#
# == Returns
# A Driver representing the given driver_url.
#
@@ -59,11 +57,11 @@
end
#
# A URL representing the driver and the place where machines come from.
# This will be stuffed in machine_spec.location['driver_url'] so that the
- # machine can be reinflated. URLs must have a unique scheme identifying the
+ # machine can be re-inflated. URLs must have a unique scheme identifying the
# driver class, and enough information to identify the place where created
# machines can be found. For AWS, this is the account number; for lxc and
# vagrant, it is the directory in which VMs and containers are.
#
# For example:
@@ -90,117 +88,105 @@
#
def driver_options
config[:driver_options] || {}
end
- #
- # Allocate a machine from the PXE/cloud/VM/container driver. This method
+
+ # Allocate a machine from the underlying service. This method
# does not need to wait for the machine to boot or have an IP, but it must
# store enough information in machine_spec.location to find the machine
# later in ready_machine.
#
# If a machine is powered off or otherwise unusable, this method may start
# it, but does not need to wait until it is started. The idea is to get the
# gears moving, but the job doesn't need to be done :)
#
- # ## Parameters
- # action_handler - the action_handler object that is calling this method; this
- # is generally a driver, but could be anything that can support the
- # interface (i.e., in the case of the test kitchen metal driver for
- # acquiring and destroying VMs).
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method
+ # @param [ChefMetal::MachineSpec] machine_spec A machine specification representing this machine.
+ # @param [Hash] machine_options A set of options representing the desired options when
+ # constructing the machine
#
- # existing_machine - a MachineSpec representing the existing machine (if any).
- #
- # machine_options - a set of options representing the desired provisioning
- # state of the machine (image name, bootstrap ssh credentials,
- # etc.). This will NOT be stored in the machine_spec, and is
- # ephemeral.
- #
- # ## Returns
- #
- # Modifies the passed-in machine_spec. Anything in here will be saved
+ # @return [ChefMetal::MachineSpec] Modifies the passed-in machine_spec. Anything in here will be saved
# back after allocate_machine completes.
#
def allocate_machine(action_handler, machine_spec, machine_options)
raise "#{self.class} does not implement allocate_machine"
end
- #
# Ready a machine, to the point where it is running and accessible via a
# transport. This will NOT allocate a machine, but may kick it if it is down.
# This method waits for the machine to be usable, returning a Machine object
# pointing at the machine, allowing useful actions like setup, converge,
# execute, file and directory.
#
- # ## Parameters
- # action_handler - the action_handler object that is calling this method; this
- # is generally a driver, but could be anything that can support the
- # interface (i.e., in the case of the test kitchen metal driver for
- # acquiring and destroying VMs).
- # machine_spec - MachineSpec representing this machine.
- # machine_options - a set of options representing the desired provisioning
- # state of the machine (image name, bootstrap ssh credentials,
- # etc.). This will NOT be stored in the machine_spec, and is
- # ephemeral.
#
- # ## Returns
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method
+ # @param [ChefMetal::MachineSpec] machine_spec A machine specification representing this machine.
+ # @param [Hash] machine_options A set of options representing the desired state of the machine
#
- # Machine object pointing at the machine, allowing useful actions like setup,
+ # @return [Machine] A machine object pointing at the machine, allowing useful actions like setup,
# converge, execute, file and directory.
#
def ready_machine(action_handler, machine_spec, machine_options)
raise "#{self.class} does not implement ready_machine"
end
- #
# Connect to a machine without allocating or readying it. This method will
# NOT make any changes to anything, or attempt to wait.
#
- # ## Parameters
- # machine_spec - MachineSpec representing this machine.
- #
- # ## Returns
- #
- # Machine object pointing at the machine, allowing useful actions like setup,
+ # @param [ChefMetal::MachineSpec] machine_spec MachineSpec representing this machine.
+ # @param [Hash] machine_options
+ # @return [Machine] A machine object pointing at the machine, allowing useful actions like setup,
# converge, execute, file and directory.
#
def connect_to_machine(machine_spec, machine_options)
raise "#{self.class} does not implement connect_to_machine"
end
- #
- # Delete the given machine (idempotent). Should destroy the machine,
+
+ # Delete the given machine -- destroy the machine,
# returning things to the state before allocate_machine was called.
#
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method
+ # @param [ChefMetal::MachineSpec] machine_spec A machine specification representing this machine.
+ # @param [Hash] machine_options A set of options representing the desired state of the machine
def destroy_machine(action_handler, machine_spec, machine_options)
raise "#{self.class} does not implement destroy_machine"
end
- #
# Stop the given machine.
#
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method
+ # @param [ChefMetal::MachineSpec] machine_spec A machine specification representing this machine.
+ # @param [Hash] machine_options A set of options representing the desired state of the machine
def stop_machine(action_handler, machine_spec, machine_options)
raise "#{self.class} does not implement stop_machine"
end
- #
# Allocate an image. Returns quickly with an ID that tracks the image.
#
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method
+ # @param [ChefMetal::ImageSpec] image_spec A machine specification representing this machine.
+ # @param [Hash] image_options A set of options representing the desired state of the machine
def allocate_image(action_handler, image_spec, image_options, machine_spec)
raise "#{self.class} does not implement create_image"
end
- #
# Ready an image, waiting till the point where it is ready to be used.
#
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method
+ # @param [ChefMetal::ImageSpec] image_spec A machine specification representing this machine.
+ # @param [Hash] image_options A set of options representing the desired state of the machine
def ready_image(action_handler, image_spec, image_options)
raise "#{self.class} does not implement ready_image"
end
+ # Destroy an image using this service.
#
- # Destroy an image.
- #
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method
+ # @param [ChefMetal::ImageSpec] image_spec A machine specification representing this machine.
+ # @param [Hash] image_options A set of options representing the desired state of the machine
def destroy_image(action_handler, image_spec, image_options)
raise "#{self.class} does not implement destroy_image"
end
#
@@ -212,38 +198,42 @@
# allocate_machine on all machine_specs.
#
# Drivers do not need to implement this; the default implementation
# calls acquire_machine in parallel.
#
- # ## Parameters
- # action_handler - the action_handler object that is calling this method; this
- # is generally a driver, but could be anything that can support the
- # interface (i.e., in the case of the test kitchen metal driver for
- # acquiring and destroying VMs).
- # specs_and_options - a hash of machine_spec -> machine_options representing the
- # machines to allocate.
- # parallelizer - an object with a parallelize() method that works like this:
+ # == Parallelizing
#
+ # The parallelizer must implement #parallelize
+ # @example Example parallelizer
# parallelizer.parallelize(specs_and_options) do |machine_spec|
# allocate_machine(action_handler, machine_spec)
# end.to_a
# # The to_a at the end causes you to wait until the parallelization is done
#
# This object is shared among other chef-metal actions, ensuring that you do
# not go over parallelization limits set by the user. Use of the parallelizer
# to parallelizer machines is not required.
#
- # ## Block
+ # == Passing a block
#
# If you pass a block to this function, each machine will be yielded to you
# as it completes, and then the function will return when all machines are
# yielded.
#
+ # @example Passing a block
# allocate_machines(action_handler, specs_and_options, parallelizer) do |machine_spec|
# ...
# end
#
+ # @param [ChefMetal::ActionHandler] action_handler The action_handler object that is calling this method; this
+ # is generally a driver, but could be anything that can support the
+ # interface (i.e., in the case of the test kitchen metal driver for
+ # acquiring and destroying VMs).
+ # @param [Hash] specs_and_options A hash of machine_spec -> machine_options representing the
+ # machines to allocate.
+ # @param [Parallelizer] parallelizer an object with a parallelize() method that works like this:
+ # @return [Array<Machine>] An array of machine objects created
def allocate_machines(action_handler, specs_and_options, parallelizer)
parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
allocate_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
yield machine_spec if block_given?
machine_spec
@@ -272,9 +262,10 @@
parallelizer.parallelize(specs_and_options) do |machine_spec, machine_options|
destroy_machine(add_prefix(machine_spec, action_handler), machine_spec, machine_options)
yield machine_spec if block_given?
end.to_a
end
+
protected
def add_prefix(machine_spec, action_handler)
AddPrefixActionHandler.new(action_handler, "[#{machine_spec.name}] ")