class Deplomat::Node

Attributes

current_path[RW]
log_to[RW]
logfile[RW]
raise_exceptions[RW]
stdout_lines_to_ignore[W]
wrap_in[RW]

Public Class Methods

new(logfile: " click to toggle source
# File lib/deplomat/node.rb, line 16
def initialize(logfile: "#{Dir.pwd}/deplomat.log", log_to: [:stdout], path: nil, log_tasks_status: true, raise_exceptions: true)
  @log_to           = log_to
  @log_tasks_status = log_tasks_status
  @logfile          = logfile
  @raise_exceptions = raise_exceptions
  @current_path     = path.sub(/\/+\Z/, '') if !path.nil? && path_exist?(path)
end

Public Instance Methods

adjusted_path(path) click to toggle source
# File lib/deplomat/node.rb, line 112
def adjusted_path(path)
  if !path.match(/\A\/|~\//)
    path = "#{@current_path}/#{path}".sub("//", "/")
  end
  File.absolute_path(path)
end
cd(path) click to toggle source
# File lib/deplomat/node.rb, line 119
def cd(path)
  path = adjusted_path(path)
  raise Deplomat::NoSuchPathError, path unless path_exist?(path)
  @current_path = if path.match(/\A\/|~\//)
    path
  else
    "#{@current_path}/#{path}"
  end.sub(/\/+\Z/, '')
end
clean(path: @current_path, except: [], leave: [0, :last]) click to toggle source
# File lib/deplomat/node.rb, line 173
def clean(path: @current_path, except: [], leave: [0, :last])
  # Gets us all entries sorted by date, most recent ones first
  entries_by_date = execute("ls -t", path, log_command: false)[:out].split("\n")
  if entries_by_date
    # Don't do anything with entries listed in :except
    entries_by_date = entries_by_date - except
    if leave
      entries_by_date.reverse! if leave[1] == :first
      entries_by_date = entries_by_date[leave[0]..entries_by_date.length]
    end
    entries_by_date.each { |entry| remove("#{path}/#{entry}") } if entries_by_date
  end
end
copy(what, where) click to toggle source
# File lib/deplomat/node.rb, line 82
def copy(what, where)
  execute("rsync -ar #{what} #{where}")
end
Also aliased as: cp
cp(what, where)
Alias for: copy
create_dir(dirname) click to toggle source
# File lib/deplomat/node.rb, line 102
def create_dir(dirname)
  execute("mkdir -p #{dirname}")
end
Also aliased as: mkdir
create_file(filename) click to toggle source
# File lib/deplomat/node.rb, line 97
def create_file(filename)
  execute("touch #{filename}")
end
Also aliased as: touch
current_requisite_number(fn=" click to toggle source
# File lib/deplomat/node.rb, line 157
def current_requisite_number(fn="#{@current_path}/.deployment_requisites_counter")
  if file_exists?(fn)
    contents = execute("cat #{fn}")[:out].chomp("\n")
    if contents =~ /\A\d+\Z/
      return contents.to_i
    else
      0
    end
  else
    log "Requisite counter file `#{fn}` doesn't exist. " +
        "Please create it manually and symlink it in the deployment script if necessary.", color: "red"
    self.close if self.respond_to?(:close)
    exit 1
  end
end
execute(command, path=@current_path, message: [], stdout_source: :stdout, log_command: true, _raise_exceptions: @raise_exceptions) { || ... } click to toggle source
# File lib/deplomat/node.rb, line 24
def execute(command, path=@current_path, message: [], stdout_source: :stdout, log_command: true, _raise_exceptions: @raise_exceptions)

  original_command = command
  if @wrap_in
    command = @wrap_in.sub("_command_", command)
  end

  message = [message] if message.kind_of?(String)
  log(message[0] + "\n", color: 'white') unless message.empty? || message.nil?

  # Respect current_path
  command_to_log = original_command
  if path
    command_to_log = "#{original_command}\n(in #{path})"
    command = "cd #{path} && #{command}"
  end

  out    = ""
  status = nil
  Open3.popen3(command) do |stdin, stdout, stderr, thread|

    # Sometimes, programs write in stderr, although there are no errors.
    # rake assets:precompile does that, for example.
    stdout_source_object = (stdout_source == :stderr ? stderr : stdout)

    log("--> " + command_to_log + "\n", color: "white") if log_command
    stdout_source_object.readlines.each_with_index do |line, i|
      self.stdout_lines_to_ignore.each do |line_to_ignore|
        line_to_ignore = line_to_ignore.to_a if line_to_ignore.kind_of?(Range)
        line_to_ignore = [line_to_ignore]    if line_to_ignore.kind_of?(Integer)
        line = nil if line_to_ignore.include?(i+1)
      end
      if line
        out << line
        log("  #{line}") if log_command
      end
    end

    error_out = ""
    status = thread.value.exitstatus.to_i
    if status > 0
      while o = stderr.gets
        error_out += o
      end
      log(error_out + "\n", color: 'red')
      if _raise_exceptions
        self.close if self.respond_to?(:close)
        raise Deplomat::ExecutionError
      end
    end
    yield if block_given?
  end

  log(message[1] + "\n", color: 'white') unless message.empty? || message.nil?

  return { status: status, out: out }
end
git_checkout(target) click to toggle source
# File lib/deplomat/node.rb, line 141
def git_checkout(target)
  execute("git checkout #{target}")
end
git_merge(source="origin", target="master") click to toggle source
# File lib/deplomat/node.rb, line 137
def git_merge(source="origin", target="master")
  execute("git merge #{source} #{target}")
end
git_pull(remote="origin", branch="master") click to toggle source
# File lib/deplomat/node.rb, line 133
def git_pull(remote="origin", branch="master")
  execute("git pull #{remote} #{branch}")
end
git_push(remote="origin", branch="master") click to toggle source
# File lib/deplomat/node.rb, line 129
def git_push(remote="origin", branch="master")
  execute("git push #{remote} #{branch}")
end
ln(source, target)
Alias for: create_symlink
log(line, color: 'light_black') click to toggle source
# File lib/deplomat/node.rb, line 187
def log(line, color: 'light_black')
  @message_color = color
  # Only calls log methods mentioned in the @log_to property
  @log_to.each { |logger| self.send("log_to_#{logger}", line) }
end
mkdir(dirname)
Alias for: create_dir
move(what, where) click to toggle source
# File lib/deplomat/node.rb, line 87
def move(what, where)
  execute("mv #{what} #{where}")
end
Also aliased as: mv
mv(what, where)
Alias for: move
remove(what) click to toggle source
# File lib/deplomat/node.rb, line 92
def remove(what)
  execute("rm -rf #{what}")
end
Also aliased as: rm
rm(what)
Alias for: remove
stdout_lines_to_ignore() click to toggle source
# File lib/deplomat/node.rb, line 8
def stdout_lines_to_ignore
  if @stdout_lines_to_ignore.kind_of?(Array)
    @stdout_lines_to_ignore
  else
    [@stdout_lines_to_ignore]
  end.compact
end
touch(filename)
Alias for: create_file
update_requisite_number!(n, counter_file_path: " click to toggle source
# File lib/deplomat/node.rb, line 145
def update_requisite_number!(n, counter_file_path: "#{@current_path}/.deployment_requisites_counter")
  current_number = current_requisite_number(counter_file_path)
  if n <= current_number
    log "New requisite number (#{n}) is below or equals the current one (#{current_number}). " + 
        "Something must have gone wrong.", color: "red"
    self.close if self.respond_to?(:close)
    exit 1
  else
    execute("echo '#{n}' > #{counter_file_path}")
  end
end

Private Instance Methods

log_to_file(line) click to toggle source
# File lib/deplomat/node.rb, line 195
def log_to_file(line)
  if @logfile
    open(@logfile, 'a') { |f| f.puts line }
  end
end
log_to_stdout(line) click to toggle source
# File lib/deplomat/node.rb, line 201
def log_to_stdout(line)
  print_to_terminal(line, color: @message_color, newline: false)
end