class Itamae::Backend::Base

Attributes

executed_commands[R]

Public Class Methods

new(options) click to toggle source
# File lib/itamae/backend.rb, line 40
def initialize(options)
  @options = options
  @backend = create_specinfra_backend
  @executed_commands = []
end

Public Instance Methods

finalize() click to toggle source
# File lib/itamae/backend.rb, line 127
def finalize
  # pass
end
get_command(*args) click to toggle source
# File lib/itamae/backend.rb, line 88
def get_command(*args)
  @backend.command.get(*args)
end
host_inventory() click to toggle source
# File lib/itamae/backend.rb, line 123
def host_inventory
  @backend.host_inventory
end
receive_file(src, dst = nil) click to toggle source
# File lib/itamae/backend.rb, line 92
def receive_file(src, dst = nil)
  if dst
    Itamae.logger.debug "Receiving a file from '#{src}' to '#{dst}'..."
  else
    Itamae.logger.debug "Receiving a file from '#{src}'..."
  end
  @backend.receive_file(src, dst)
end
run_command(commands, options = {}) click to toggle source
# File lib/itamae/backend.rb, line 46
def run_command(commands, options = {})
  options = {error: true}.merge(options)

  command = build_command(commands, options)
  Itamae.logger.debug "Executing `#{command}`..."

  result = nil

  Itamae.logger.with_indent do
    reset_output_handler

    result = run_command_with_profiling(command)

    flush_output_handler_buffer

    if result.exit_status == 0 || !options[:error]
      method = :debug
      message = "exited with #{result.exit_status}"
    else
      method = :error
      message = "Command `#{command}` failed. (exit status: #{result.exit_status})"

      unless Itamae.logger.level == ::Logger::DEBUG
        result.stdout.each_line do |l|
          log_output_line("stdout", l, :error)
        end
        result.stderr.each_line do |l|
          log_output_line("stderr", l, :error)
        end
      end
    end

    Itamae.logger.public_send(method, message)
  end

  if options[:error] && result.exit_status != 0
    raise CommandExecutionError
  end

  result
end
send_directory(src, dst) click to toggle source
# File lib/itamae/backend.rb, line 112
def send_directory(src, dst)
  Itamae.logger.debug "Sending a directory from '#{src}' to '#{dst}'..."
  unless ::File.exist?(src)
    raise SourceNotExistError, "The directory '#{src}' doesn't exist."
  end
  unless ::File.directory?(src)
    raise SourceNotExistError, "'#{src}' is not a directory."
  end
  @backend.send_directory(src, dst)
end
send_file(src, dst) click to toggle source
# File lib/itamae/backend.rb, line 101
def send_file(src, dst)
  Itamae.logger.debug "Sending a file from '#{src}' to '#{dst}'..."
  unless ::File.exist?(src)
    raise SourceNotExistError, "The file '#{src}' doesn't exist."
  end
  unless ::File.file?(src)
    raise SourceNotExistError, "'#{src}' is not a file."
  end
  @backend.send_file(src, dst)
end

Private Instance Methods

build_command(commands, options) click to toggle source
# File lib/itamae/backend.rb, line 168
def build_command(commands, options)
  if commands.is_a?(Array)
    command = commands.map do |cmd|
      cmd.shellescape
    end.join(' ')
  else
    command = commands
  end

  cwd = options[:cwd]
  if cwd
    command = "cd #{cwd.shellescape} && #{command}"
  end

  user = options[:user]
  if user
    command = "cd ~#{user.shellescape} ; #{command}"
    command = "sudo -H -u #{user.shellescape} -- #{shell.shellescape} -c #{command.shellescape}"
  end

  command
end
create_specinfra_backend() click to toggle source
# File lib/itamae/backend.rb, line 133
def create_specinfra_backend
  raise NotImplementedError
end
flush_output_handler_buffer() click to toggle source
# File lib/itamae/backend.rb, line 156
def flush_output_handler_buffer
  @buf.each do |output_name, line|
    next if line.empty?
    log_output_line(output_name, line)
  end
end
log_output_line(output_name, line, severity = :debug) click to toggle source
# File lib/itamae/backend.rb, line 163
def log_output_line(output_name, line, severity = :debug)
  line = line.gsub(/[[:cntrl:]]/, '')
  Itamae.logger.public_send(severity, "#{output_name} | #{line}")
end
reset_output_handler() click to toggle source
# File lib/itamae/backend.rb, line 137
def reset_output_handler
  @buf = {}
  %w!stdout stderr!.each do |output_name|
    @buf[output_name] = ""
    handler = lambda do |str|
      lines = str.split(/\r?\n/, -1)
      @buf[output_name] += lines.pop
      unless lines.empty?
        lines[0] = @buf[output_name] + lines[0]
        @buf[output_name] = ""
        lines.each do |l|
          log_output_line(output_name, l)
        end
      end
    end
    @backend.public_send("#{output_name}_handler=", handler)
  end
end
run_command_with_profiling(command) click to toggle source
# File lib/itamae/backend.rb, line 195
def run_command_with_profiling(command)
  start_at = Time.now
  result = @backend.run_command(command)
  duration = Time.now.to_f - start_at.to_f

  @executed_commands << {command: command, duration: duration}

  result
end
shell() click to toggle source
# File lib/itamae/backend.rb, line 191
def shell
  @options[:shell] || '/bin/sh'
end