class ConcourseTechnician::VolumeReaper

Public Instance Methods

damaged() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 33
def damaged
  detected? ? exit : abort
end
recent_events() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 22
def recent_events
  @recent_events ||= logs.read(100).map do |event|
    begin
      JSON.load event
    rescue JSON::ParserError
      nil
    end
  end.compact
end
repair() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 38
def repair
  detected? ? repair! : abort
end
timestamps() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 15
def timestamps
  @timestamps ||= worker.journal.read(1000).map do |entry|
    Time.parse entry.split.first
  end.sort
end

Private Instance Methods

dead_volumes() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 113
def dead_volumes
  Dir.glob("#{volumes_root}/dead/*")
end
detected?() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 75
def detected?
  stagnant_logs?.tap do |status|
    report "Most recent log entry @ #{timestamps.last}"
    report "Logs seem stagnant? #{status}"
  end && reaping_failure?.tap do |status|
    report "Recently volume reaping failure? #{status}"
  end
end
env?(key) { |: false| ... } click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 45
def env?(key)
  if ![nil, 'nil', 'false'].include? ENV[key.to_s.upcase]
    true
  else
    block_given? ? yield : false
  end
end
logs() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 90
def logs
  @logs ||= ::Systemized::Journal.new('concourse-worker', output: 'cat')
end
reap_dead_volumes() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 118
def reap_dead_volumes
  report "Reaping #{dead_volumes.size} dead volumes..."
  dead_volumes.each do |volume|
    FileUtils.rmtree volume, verbose: env?(:QUIET), noop: env?(:NOOP)
  end
end
reap_subvolumes() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 107
def reap_subvolumes
  report "Reaping #{subvolumes.size} subvolumes..."
  subvolumes.each(&:delete).all?(&:deleted?) unless env?(:NOOP)
end
reaping_failure?() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 61
def reaping_failure?
  env?(:reaping_failure) do
    recent_events.any? do |event|
      event['message'] == 'baggageclaim.tick.failed-to-reap'
    end
  end
end
repair!() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 126
def repair!
  worker.stop if worker.active? && !env?(:NOOP)
  reap_subvolumes
  reap_dead_volumes
  worker.start unless env?(:NOOP)
end
report(message) click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 70
def report(message)
  STDERR.puts message.to_s unless env?(:QUIET)
end
stagnant_logs?() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 54
def stagnant_logs?
  env?(:stagnant_logs) do
    (Time.now - timestamps.last) > (timestamps.last - timestamps.first)
  end
end
subvolumes() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 102
def subvolumes
  @subvolumes ||= ::Btrfs::Volume.new(volumes_root).subvolumes
end
volumes_root() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 95
def volumes_root
  @volumes_root ||= ENV.fetch('VOLUMES_ROOT') do
    settings.fetch('volumes_root') { '/concourse/volumes' }
  end
end
worker() click to toggle source
# File lib/concourse-technician/volume_reaper.rb, line 85
def worker
  @worker = ::Systemized::Service.new('concourse-worker')
end