class Dopi::Command

Attributes

hash[R]
is_verify_command[R]
node[R]

Public Class Methods

create_plugin_instance(command_parser, step, node, is_verify_command = false) click to toggle source
# File lib/dopi/command.rb, line 19
def self.create_plugin_instance(command_parser, step, node, is_verify_command = false)
  plugin_type = PluginManager.get_plugin_name(self) + '/'
  plugin_full_name = plugin_type + command_parser.plugin
  Dopi.log.debug("Creating instance of plugin #{plugin_full_name}")
  PluginManager.create_instance(plugin_full_name, command_parser, step, node, is_verify_command)
end
delete_plugin_default(node_name, key) click to toggle source

delete a specific default for the node

# File lib/dopi/command.rb, line 49
def self.delete_plugin_default(node_name, key)
  @plugin_defaults ||= {}
  @plugin_defaults[node_name] ||= {}
  @plugin_defaults[node_name].delete(key)
end
delete_plugin_defaults(node_name) click to toggle source

delete all the defaults on this plugin for the node

# File lib/dopi/command.rb, line 43
def self.delete_plugin_defaults(node_name)
  @plugin_defaults ||= {}
  @plugin_defaults[node_name] = {}
end
inherited(klass) click to toggle source
# File lib/dopi/command.rb, line 15
def self.inherited(klass)
  PluginManager << klass
end
new(command_parser, step, node, is_verify_command) click to toggle source
# File lib/dopi/command.rb, line 57
def initialize(command_parser, step, node, is_verify_command)
  @command_parser    = command_parser
  @step              = step
  @node              = node
  @is_verify_command = is_verify_command
  @hash              = merged_hash
  log(:debug, "Plugin created with merged command hash: #{hash.inspect}")
  # make sure verify commands are initialized as well
  verify_commands
end
plugin_defaults(node_name) click to toggle source
# File lib/dopi/command.rb, line 32
def self.plugin_defaults(node_name)
  @plugin_defaults ||= {}
  @plugin_defaults[node_name] ||= {}
end
set_plugin_defaults(node_name, hash) click to toggle source
# File lib/dopi/command.rb, line 26
def self.set_plugin_defaults(node_name, hash)
  @plugin_defaults ||= {}
  @plugin_defaults[node_name] ||= {}
  @plugin_defaults[node_name].merge!(DopCommon::HashParser.symbolize_keys(hash))
end
wipe_plugin_defaults() click to toggle source

wipe all the defaults for this plugin

# File lib/dopi/command.rb, line 38
def self.wipe_plugin_defaults
  @plugin_defaults = {}
end

Public Instance Methods

load_state(state_hash) click to toggle source
# File lib/dopi/command.rb, line 147
def load_state(state_hash)
  command_state = state_hash[:command_state] || :ready
  unless command_state == :ready
    @state = command_state
    state_changed
  end
end
merged_hash() click to toggle source
# File lib/dopi/command.rb, line 68
def merged_hash
  if @command_parser.hash.kind_of?(Hash)
    self.class.plugin_defaults(@node.name).merge(@command_parser.hash)
  else
    self.class.plugin_defaults(@node.name)
  end
end
meta_run(noop = false) click to toggle source
# File lib/dopi/command.rb, line 79
def meta_run(noop = false)
  return if skip_run?(noop)
  state_run unless noop
  # Nest timeout in itself to fix working in combination with popen3() used
  # by command connectors
  Timeout::timeout(plugin_timeout) do
    Timeout::timeout(plugin_timeout) do
      log(:info, "Running command #{name}") unless @is_verify_command
      if noop
        run_noop
      else
        if run
          if verify_after_run
            verify_commands_ok? or
              raise CommandExecutionError, "Verify commands failed to confirm a successful run"
          end
          state_finish
          log(:info, "#{name} [OK]") if state_done?
        else
          state_fail
          if @is_verify_command
            log(:info, "#{name} [FAILED]")
          else
            log(:error, "#{name} [FAILED]")
            log_file = @step.plan.context_logger.current_log_file
            log(:error, "Check the log file #{log_file} for the full debug log of the node")
          end
        end
      end
    end
  end
rescue GracefulExit
  log(:info, "Command excited gracefuly, resetting to ready")
  state_reset(true) unless noop
rescue Timeout::Error
  log(:error, "Command timed out (plugin_timeout is set to #{plugin_timeout})", false)
  state_fail unless noop
  send_signal(:abort)
rescue CommandExecutionError => e
  log(:error, "Command failed: #{e.message}", false)
  log_file = @step.plan.context_logger.current_log_file
  log(:error, "Check the log file #{log_file} for the full debug log of the node", false)
  Dopi.log.error(e) if DopCommon.config.trace
  state_fail unless noop
rescue => e
  log(:error, "Unexpected error!!! This is a Bug", false)
  Dopi.log.error(e.class)
  Dopi.log.error(e.message)
  Dopi.log.error(e.backtrace)
  state_fail unless noop
  raise e
end
meta_valid?() click to toggle source
# File lib/dopi/command.rb, line 132
def meta_valid?
  validity = valid?
  validity = false unless verify_commands.all? do |verify_command|
    begin
      verify_command.meta_valid?
    rescue PluginLoaderError => e
      Dopi.log.error("Step '#{@step.name}': Can't load plugin #{verify_command.plugin}: #{e.message}")
    end
  end
  validity
end
state_hash() click to toggle source
# File lib/dopi/command.rb, line 155
def state_hash
  {:command_state => @state}
end

Private Instance Methods

log(severity, message, overwrite = true) click to toggle source
# File lib/dopi/command.rb, line 214
def log(severity, message, overwrite = true)
  # Ignore verify command errors, because they are expected
  if @is_verify_command && overwrite
    severity = :debug if severity == :error || severity == :warn
  end
  # TODO: implement Node specific logging
  # for now we simply forward to the global DOPi logger
  Dopi.log.log(Logger.const_get(severity.upcase), log_prefix + message)
end
log_prefix() click to toggle source
# File lib/dopi/command.rb, line 206
def log_prefix
  if @is_verify_command
    "  [Verify] #{@node.name} : "
  else
    "  [Command] #{@node.name} : "
  end
end
run() click to toggle source
# File lib/dopi/command.rb, line 161
def run
  raise Dopi::CommandExecutionError, "No run method implemented in plugin #{name}"
end
run_noop() click to toggle source
# File lib/dopi/command.rb, line 165
def run_noop
  Dopi.log.error("The plugin #{name} does not support noop runs and will not show the command")
end
skip_run?(noop = false) click to toggle source
# File lib/dopi/command.rb, line 174
def skip_run?(noop = false)
  if state_done?
    log(:info, "Is already in state 'done'. Skipping")
    true
  elsif verify_commands.any? && verify_commands_ok?
    if noop
      log(:info, "All verify commands ok. Skipping")
    else
      log(:info, "All verify commands ok. Skipping and marked as 'done'")
      state_run
      state_finish
    end
    true
  else
    false
  end
end
validate() click to toggle source
# File lib/dopi/command.rb, line 169
def validate
  Dopi.log.warn("No 'validate' method implemented in plugin #{name}. Validation not possible")
  true
end
verify_commands() click to toggle source
# File lib/dopi/command.rb, line 192
def verify_commands
  @verify_commands ||= parsed_verify_commands.map do |command|
    Dopi::Command.create_plugin_instance(command, @step, @node, true)
  end
end
verify_commands_ok?() click to toggle source
# File lib/dopi/command.rb, line 198
def verify_commands_ok?
  verify_commands.all? do |command|
    command.state_reset(true)
    command.meta_run
    command.state_done?
  end
end