class Cronicle::Driver

Constants

CRON_DIRS

Attributes

hosts[R]

Public Class Methods

new(hosts, options = nil) click to toggle source
# File lib/cronicle/driver.rb, line 6
def initialize(hosts, options = nil)
  @hosts = hosts
  @options = options
end

Public Instance Methods

create_job(user, name, job) click to toggle source
# File lib/cronicle/driver.rb, line 85
def create_job(user, name, job)
  execute do
    if job[:bundle]
      mkgemfile(user, name, job[:bundle])
      bundle(user, name)
    end
  end

  create_or_update_job(user, name, job)
end
create_or_update_job(user, name, job, script = nil) click to toggle source
# File lib/cronicle/driver.rb, line 112
def create_or_update_job(user, name, job, script = nil)
  execute do
    log_opts = {:host => host.hostname, :user => user, :job => name}
    log_opts[:color] = script ? :green : :cyan
    log_msg = (script ? 'Update' : 'Create') + " job: schedule=#{job[:schedule].inspect}"

    if host.options[:verbose]
      content_orig = script ? script[:content] : ''
      log_msg << "\n" << Cronicle::Utils.diff(content_orig, job[:content])
    end

    log_for_cronicle(:info, log_msg, log_opts)

    unless host.options[:dry_run]
      mktemp(user) do |temp_dir, user_temp_dir|
        libexec_script = script_path(user, name)

        upload_script(temp_dir, name, job[:content]) do |temp_script|
          temp_entry = temp_script + '.entry'
          sudo(:execute, :mkdir, '-p', user_libexec_dir(user))
          sudo(:execute, :cp, temp_script, libexec_script)
          sudo(:execute, :touch, user_crontab(user))
          delete_cron_entry(user, name)
          add_cron_entry(user, name, job[:schedule], user_temp_dir, job[:bundle])
        end
      end
    end
  end
end
delete_job(scripts_by_user, target_name = nil) click to toggle source
# File lib/cronicle/driver.rb, line 142
def delete_job(scripts_by_user, target_name = nil)
  execute do
    scripts_by_user.each do |user, scripts|
      scripts.each do |name, script|
        next if target_name && target_name != name

        log_opts = {:color => :red, :host => host.hostname, :user => user, :job => name}
        log_msg = "Delete job: schedule=#{script[:schedule].inspect}"
        log_msg << "\n" << Cronicle::Utils.diff(script[:content], '') if host.options[:verbose]
        log_for_cronicle(:info, log_msg, log_opts)

        unless host.options[:dry_run]
          delete_cron_entry(user, name)
          sudo(:execute, :rm, '-f', script[:path], :raise_on_non_zero_exit => false)
          sudo(:execute, :rm, '-rf', gemfile_dir(user, name), :raise_on_non_zero_exit => false)
        end
      end
    end
  end
end
execute(&block) click to toggle source
# File lib/cronicle/driver.rb, line 11
def execute(&block)
  coordinator = SSHKit::Coordinator.new(@hosts)
  hosts = coordinator.hosts

  hosts.each do |host|
    host.instance_variable_set(:@options, @options)
  end

  runner_opts = @options[:runner_options] || {}
  runner = SSHKit::Runner::Group.new(hosts, runner_opts, &block)
  runner.group_size = @options[:concurrency]
  runner.execute
end
execute_job(user, jobs) click to toggle source
# File lib/cronicle/driver.rb, line 37
def execute_job(user, jobs)
  execute do
    mktemp do |temp_dir|
      jobs.each do |name, job|
        log_opts = {:color => :cyan, :host => host.hostname, :user => user, :job => name}
        log_msg = 'Execute job'

        if host.options[:dry_run]
          if host.options[:verbose]
            content = job[:content].each_line.map {|l| ' ' + l }.join
            log_msg << "\n" << content.chomp << "\n"
          end

          log_for_cronicle(:info, log_msg, log_opts)
          next
        else
          log_for_cronicle(:info, log_msg, log_opts)
        end

        upload_script(temp_dir, name, job[:content]) do |temp_script|
          host_user_job = {:host => host.hostname, :user => user, :job => name}

          sniffer = proc do |obj|
            out = obj.kind_of?(SSHKit::Command) ? obj.stdout : obj.to_s

            out.each_line do |line|
              log_for_cronicle(:info, line, host_user_job)
            end
          end

          exec_opts = {:user => user, :raise_on_non_zero_exit => false, :sniffer => sniffer}

          if job[:bundle]
            mkgemfile(user, name, job[:bundle], temp_dir)
            bundle(user, name, temp_dir)

            with_bundle(user, name, temp_dir) do
              sudo(:_execute, bundler_path, :exec, temp_script, exec_opts)
            end
          else
            sudo(:_execute, temp_script, exec_opts)
          end
        end
      end
    end
  end
end
export_crontab() click to toggle source
# File lib/cronicle/driver.rb, line 25
def export_crontab
  crontabs_by_host = {}
  libexec_by_host = {}

  execute do
    crontabs_by_host[host.hostname] = fetch_crontabs
    libexec_by_host[host.hostname] = fetch_libexec_scripts
  end

  [crontabs_by_host, libexec_by_host]
end
test_sudo() click to toggle source
# File lib/cronicle/driver.rb, line 163
def test_sudo
  ok = false

  execute do
    ok = sudo(:execute, :echo, :raise_on_non_zero_exit => false)

    unless ok
      log_for_cronicle(:error, 'incorrect sudo password', :color => :red, :host => host.hostname)
    end
  end

  ok
end
update_job(user, name, job, script) click to toggle source
# File lib/cronicle/driver.rb, line 96
def update_job(user, name, job, script)
  job_content = job[:content].chomp
  script_content = script[:content].chomp

  execute do
    if job[:bundle]
      mkgemfile(user, name, job[:bundle])
      bundle(user, name)
    end
  end

  if [:schedule, :content].any? {|k| job[k].chomp != script[k].chomp }
    create_or_update_job(user, name, job, script)
  end
end