61 lines
1.8 KiB
Ruby
61 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module BackgroundMigration
|
|
# This class is responsible to update all sha256 fingerprints within the keys table
|
|
class MigrateFingerprintSha256WithinKeys
|
|
# Temporary AR table for keys
|
|
class Key < ActiveRecord::Base
|
|
include EachBatch
|
|
|
|
self.table_name = 'keys'
|
|
self.inheritance_column = :_type_disabled
|
|
end
|
|
|
|
TEMP_TABLE = 'tmp_fingerprint_sha256_migration'
|
|
|
|
def perform(start_id, stop_id)
|
|
ActiveRecord::Base.transaction do
|
|
execute(<<~SQL)
|
|
CREATE TEMPORARY TABLE #{TEMP_TABLE}
|
|
(id bigint primary key, fingerprint_sha256 bytea not null)
|
|
ON COMMIT DROP
|
|
SQL
|
|
|
|
fingerprints = []
|
|
Key.where(id: start_id..stop_id, fingerprint_sha256: nil).find_each do |regular_key|
|
|
if fingerprint = generate_ssh_public_key(regular_key.key)
|
|
bytea = ActiveRecord::Base.connection.escape_bytea(Base64.decode64(fingerprint))
|
|
|
|
fingerprints << {
|
|
id: regular_key.id,
|
|
fingerprint_sha256: bytea
|
|
}
|
|
end
|
|
end
|
|
|
|
Gitlab::Database.bulk_insert(TEMP_TABLE, fingerprints) # rubocop:disable Gitlab/BulkInsert
|
|
|
|
execute("ANALYZE #{TEMP_TABLE}")
|
|
|
|
execute(<<~SQL)
|
|
UPDATE keys
|
|
SET fingerprint_sha256 = t.fingerprint_sha256
|
|
FROM #{TEMP_TABLE} t
|
|
WHERE keys.id = t.id
|
|
SQL
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def generate_ssh_public_key(regular_key)
|
|
Gitlab::SSHPublicKey.new(regular_key).fingerprint("SHA256")&.gsub("SHA256:", "")
|
|
end
|
|
|
|
def execute(query)
|
|
ActiveRecord::Base.connection.execute(query)
|
|
end
|
|
end
|
|
end
|
|
end
|