debian-mirror-gitlab/lib/gitlab/verify/batch_verifier.rb

105 lines
2.7 KiB
Ruby
Raw Normal View History

2019-02-15 15:39:39 +05:30
# frozen_string_literal: true
2018-03-27 19:54:05 +05:30
module Gitlab
module Verify
class BatchVerifier
attr_reader :batch_size, :start, :finish
def initialize(batch_size:, start: nil, finish: nil)
@batch_size = batch_size
@start = start
@finish = finish
2018-11-08 19:23:39 +05:30
fix_google_api_logger
2018-03-27 19:54:05 +05:30
end
# Yields a Range of IDs and a Hash of failed verifications (object => error)
def run_batches(&blk)
2018-11-08 19:23:39 +05:30
all_relation.in_batches(of: batch_size, start: start, finish: finish) do |batch| # rubocop: disable Cop/InBatches
range = batch.first.id..batch.last.id
failures = run_batch_for(batch)
2018-03-27 19:54:05 +05:30
yield(range, failures)
end
end
def name
2021-06-08 01:23:25 +05:30
raise NotImplementedError
2018-03-27 19:54:05 +05:30
end
def describe(_object)
2021-06-08 01:23:25 +05:30
raise NotImplementedError
2018-03-27 19:54:05 +05:30
end
private
2018-11-08 19:23:39 +05:30
def run_batch_for(batch)
batch.map { |upload| verify(upload) }.compact.to_h
2018-03-27 19:54:05 +05:30
end
def verify(object)
2018-11-08 19:23:39 +05:30
local?(object) ? verify_local(object) : verify_remote(object)
2021-06-08 01:23:25 +05:30
rescue StandardError => err
2018-11-08 19:23:39 +05:30
failure(object, err.inspect)
end
def verify_local(object)
2018-03-27 19:54:05 +05:30
expected = expected_checksum(object)
actual = actual_checksum(object)
2018-11-08 19:23:39 +05:30
return failure(object, 'Checksum missing') unless expected.present?
return failure(object, 'Checksum mismatch') unless expected == actual
success
end
2018-03-27 19:54:05 +05:30
2018-11-08 19:23:39 +05:30
# We don't calculate checksum for remote objects, so just check existence
def verify_remote(object)
return failure(object, 'Remote object does not exist') unless remote_object_exists?(object)
success
end
def success
2018-03-27 19:54:05 +05:30
nil
2018-11-08 19:23:39 +05:30
end
def failure(object, message)
[object, message]
end
# It's already set to Logger::INFO, but acts as if it is set to
# Logger::DEBUG, and this fixes it...
def fix_google_api_logger
2020-07-10 23:44:40 +05:30
require 'google/apis'
Google::Apis.logger.level = Logger::INFO
2018-03-27 19:54:05 +05:30
end
# This should return an ActiveRecord::Relation suitable for calling #in_batches on
2018-11-08 19:23:39 +05:30
def all_relation
2021-06-08 01:23:25 +05:30
raise NotImplementedError
2018-11-08 19:23:39 +05:30
end
# Should return true if the object is stored locally
def local?(_object)
2021-06-08 01:23:25 +05:30
raise NotImplementedError
2018-03-27 19:54:05 +05:30
end
# The checksum we expect the object to have
def expected_checksum(_object)
2021-06-08 01:23:25 +05:30
raise NotImplementedError
2018-03-27 19:54:05 +05:30
end
# The freshly-recalculated checksum of the object
def actual_checksum(_object)
2021-06-08 01:23:25 +05:30
raise NotImplementedError
2018-03-27 19:54:05 +05:30
end
2018-11-08 19:23:39 +05:30
# Be sure to perform a hard check of the remote object (don't just check DB value)
def remote_object_exists?(object)
2021-06-08 01:23:25 +05:30
raise NotImplementedError
2018-11-08 19:23:39 +05:30
end
2018-03-27 19:54:05 +05:30
end
end
end