class Pocketknife

Pocketknife

About

Pocketknife is a devops tool for managing computers running chef-solo. Using Pocketknife, you create a project that describes the configuration of your computers and then apply it to bring them to the intended state.

For information on using the pocketknife tool, please see the {file:README.md README.md} file. The rest of this documentation is intended for those writing code using the Pocketknife API.

Important methods

Important classes

Constants

ExecutionError

ExecutionError

Exception raised when something goes wrong executing commands against remote host.

InvalidTransferMechanism

InvalidTransferMechanism

Exception raised when given an invalid transfer mechanism, e.g. not :tar or :rsync.

NoSuchNode

NoSuchNode

Exception raised when asked to perform an operation on an unknown node.

NodeError

NodeError

An error with a {Pocketknife::Node}. This is meant to be subclassed by a more specific error.

NotInstalling

NotInstalling

Exception raised when Chef is not available ohn a node, but user asked not to install it.

RsyncError

RsyncError

Exception raised if rsync command failed.

UnsupportedInstallationPlatform

UnsupportedInstallationPlatform

Exception raised when asked to install Chef on a node with an unsupported platform.

Attributes

can_install[RW]

Should Chef and its dependencies be installed automatically if not found on a node?

@return [Nil, Boolean] true means perform the installation without prompting, false means quit if Chef isn’t found, and nil means prompt the user to decide this interactively.

node_manager[RW]

@return [Pocketknife::NodeManager] This instance’s node manager.

runlist[RW]

@return [Nil, String] Override runlist with a comma-separated list of recipes and roles.

transfer_mechanism[RW]

@return [Symbol] Use :rsync or :tar to transfer files.

verbosity[RW]

Amount of detail to display.

@return [Nil, Boolean] true means verbose, nil means normal, false means quiet.

Public Class Methods

cli(args) click to toggle source

Runs the interpreter using arguments provided by the command-line. Run pocketknife -h or review the code below to see what command-line arguments are accepted.

Example:

# Display command-line help:
Pocketknife.cli('-h')

@param [Array<String>] args A list of arguments from the command-line, which may include options (e.g. -h). @return [void] @raise [SystemExit] Something catastrophic happened, e.g. user passed invalid options to interpreter.

# File lib/pocketknife.rb, line 62
  def self.cli(args)
    pocketknife = Pocketknife.new
    timer = Time.now

    OptionParser.new do |parser|
      parser.banner = <<-HERE
USAGE: pocketknife [options] [nodes]

EXAMPLES:
  # Create a new project called PROJECT
  pocketknife -c PROJECT

  # Apply configuration to a node called NODE
  pocketknife NODE

OPTIONS:
      HERE

      options = {}

      parser.on("-c", "--create PROJECT", "Create project") do |name|
        pocketknife.create(name)
        return
      end

      parser.on("-V", "--version", "Display version number") do |name|
        puts "Pocketknife #{Pocketknife::Version::STRING}"
        return
      end

      parser.on("-v", "--verbose", "Display detailed status information") do |name|
        pocketknife.verbosity = true
      end

      parser.on("-q", "--quiet", "Display minimal status information") do |v|
        pocketknife.verbosity = false
      end

      parser.on("-u", "--upload", "Upload configuration, but don't apply it") do |v|
        options[:upload] = true
      end

      parser.on("-a", "--apply", "Runs cheef to apply already-uploaded configuration") do |v|
        options[:apply] = true
      end

      parser.on("-i", "--install", "Install Chef automatically") do |v|
        pocketknife.can_install = true
      end

      parser.on("-I", "--noinstall", "Don't install Chef automatically") do |v|
        pocketknife.can_install = false
      end

      parser.on("-r", "--runlist RUNLIST", "Override runlist with a comma-separated list of recipes and roles") do |v|
        pocketknife.runlist = v
      end

      transfer_mechanisms = %w[rsync tar]
      parser.on("-t", "--transfer MECHANISM", transfer_mechanisms, "Specify transfer mechanism (#{transfer_mechanisms.join(', ')})") do |v|
        pocketknife.transfer_mechanism = v.to_sym
      end

      begin
        arguments = parser.parse!
      rescue OptionParser::ParseError => e
        puts parser
        puts
        puts "ERROR: #{e}"
        exit -1
      end

      nodes = arguments

      if nodes.empty?
        puts parser
        puts
        puts "ERROR: No nodes specified."
        exit -1
      end

      begin
        if options[:upload]
          pocketknife.upload(nodes)
        end

        if options[:apply]
          pocketknife.apply(nodes)
        end

        if not options[:upload] and not options[:apply]
          pocketknife.deploy(nodes)
        end

        pocketknife.say("* SUCCESS! Took #{"%0.2f" % [Time.now-timer]} seconds")
      rescue NodeError => e
        puts "! #{e.node}: #{e}"
        exit -1
      rescue Errno::ENOENT => e
        puts "! #{e.message}"
        exit -1
      end
    end
  end
new(opts={}) click to toggle source

Instantiates a new Pocketknife.

@option [Nil, Boolean] verbosity Amount of detail to display. true means verbose, nil means normal, false means quiet. @option [Nil, Boolean] install Install Chef and its dependencies if needed? true means do so automatically, false means don’t, and nil means display a prompt to ask the user what to do.

# File lib/pocketknife.rb, line 197
def initialize(opts={})
  self.verbosity   = opts[:verbosity]
  self.can_install = opts[:install]
  self.runlist     = opts[:runlist]
  self.transfer_mechanism = opts[:transfer_mechanism] || :rsync

  self.node_manager = NodeManager.new(self)
end
version() click to toggle source

Returns the software’s version.

@return [String] A version string, e.g. 0.0.1.

# File lib/pocketknife.rb, line 170
def self.version
  return Pocketknife::Version::STRING
end

Public Instance Methods

apply(nodes) click to toggle source

Applies configurations to remote nodes.

@param [Array<String>] nodes A list of node names. @return [void]

# File lib/pocketknife.rb, line 294
def apply(nodes)
  node_manager.assert_known(nodes)

  for node in nodes
    node_manager.find(node).apply
  end
end
create(project) click to toggle source

Creates a new project directory.

@param [String] project The name of the project directory to create. @yield status information to the optionally supplied block. @yieldparam [String] path The path of the file or directory created. @return [void]

# File lib/pocketknife.rb, line 233
def create(project)
  self.say("* Creating project in directory: #{project}")

  dir = Pathname.new(project)

  %w[
    nodes
    roles
    cookbooks
    site-cookbooks
  ].each do |subdir|
    target = (dir + subdir)
    unless target.exist?
      FileUtils.mkdir_p(target)
      self.say("- #{target}/")
    end
  end

  return true
end
deploy(nodes) click to toggle source

Deploys configuration to the nodes, calls {#upload} and {#apply}.

@param [Array<String>] nodes A list of node names. @return [void]

# File lib/pocketknife.rb, line 266
def deploy(nodes)
  node_manager.assert_known(nodes)

  Node.prepare_upload do
    for node in nodes
      node_manager.find(node).deploy
    end
  end
end
node(name) click to toggle source

Returns a node.

@param [String] name The name of the node. @return [Pocketknife::Node]

# File lib/pocketknife.rb, line 258
def node(name)
  return node_manager.find(name)
end
say(message, importance=nil) click to toggle source

Displays a message, but only if it’s important enough.

@param [String] message The message to display. @param [Nil, Boolean] importance How important is this? true means important, nil means normal, false means unimportant. @return [void]

# File lib/pocketknife.rb, line 211
def say(message, importance=nil)
  display = \
    case self.verbosity
    when true
      true
    when nil
      importance != false
    else
      importance == true
    end

  if display
    puts message
  end
end
upload(nodes) click to toggle source

Uploads configuration information to remote nodes.

@param [Array<String>] nodes A list of node names. @return [void]

# File lib/pocketknife.rb, line 280
def upload(nodes)
  node_manager.assert_known(nodes)

  Node.prepare_upload do
    for node in nodes
      node_manager.find(node).upload
    end
  end
end