Skip to content
Snippets Groups Projects
Commit 89b4304f authored by Shinya Maeda's avatar Shinya Maeda
Browse files

Add background migrations to arhive legacy traces

parent ee111285
No related branches found
No related tags found
No related merge requests found
class ArchiveLegacyTraces < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
BATCH_SIZE = 10_000
BACKGROUND_MIGRATION_CLASS = 'ArchiveLegacyTraces'
disable_ddl_transaction!
class Build < ActiveRecord::Base
include EachBatch
self.table_name = 'ci_builds'
self.inheritance_column = :_type_disabled # Disable STI
scope :finished, -> { where(status: [:success, :failed, :canceled]) }
scope :without_new_traces, ->() do
where('NOT EXISTS (?)',
::ArchiveLegacyTraces::JobArtifact.select(1).trace.where('ci_builds.id = ci_job_artifacts.job_id'))
end
end
class JobArtifact < ActiveRecord::Base
self.table_name = 'ci_job_artifacts'
enum file_type: {
archive: 1,
metadata: 2,
trace: 3
}
end
def up
queue_background_migration_jobs_by_range_at_intervals(
::ArchiveLegacyTraces::Build.finished.without_new_traces,
BACKGROUND_MIGRATION_CLASS,
5.minutes,
batch_size: BATCH_SIZE)
end
def down
# noop
end
end
Loading
Loading
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
 
ActiveRecord::Schema.define(version: 20180529093006) do
ActiveRecord::Schema.define(version: 20180529152628) do
 
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Loading
Loading
# frozen_string_literal: true
# rubocop:disable Metrics/AbcSize
# rubocop:disable Style/Documentation
module Gitlab
module BackgroundMigration
class ArchiveLegacyTraces
class Build < ActiveRecord::Base
include ::HasStatus
self.table_name = 'ci_builds'
self.inheritance_column = :_type_disabled # Disable STI
belongs_to :project, foreign_key: :project_id, class_name: 'ArchiveLegacyTraces::Project'
has_one :job_artifacts_trace, -> () { where(file_type: ArchiveLegacyTraces::JobArtifact.file_types[:trace]) }, class_name: 'ArchiveLegacyTraces::JobArtifact', foreign_key: :job_id
has_many :trace_chunks, foreign_key: :build_id, class_name: 'ArchiveLegacyTraces::BuildTraceChunk'
scope :finished, -> { where(status: [:success, :failed, :canceled]) }
scope :without_new_traces, ->() do
finished.where('NOT EXISTS (?)',
BackgroundMigration::ArchiveLegacyTraces::JobArtifact.select(1).trace.where('ci_builds.id = ci_job_artifacts.job_id'))
end
def trace
::Gitlab::Ci::Trace.new(self)
end
def trace=(data)
raise NotImplementedError
end
def old_trace
read_attribute(:trace)
end
def erase_old_trace!
update_column(:trace, nil)
end
end
class JobArtifact < ActiveRecord::Base
self.table_name = 'ci_job_artifacts'
belongs_to :build
belongs_to :project
mount_uploader :file, JobArtifactUploader
enum file_type: {
archive: 1,
metadata: 2,
trace: 3
}
end
class BuildTraceChunk < ActiveRecord::Base
self.table_name = 'ci_build_trace_chunks'
belongs_to :build
end
class Project < ActiveRecord::Base
self.table_name = 'projects'
has_many :builds, foreign_key: :project_id, class_name: 'ArchiveLegacyTraces::Build'
end
def perform(start_id, stop_id)
BackgroundMigration::ArchiveLegacyTraces::Build
.finished
.without_new_traces
.where(id: (start_id..stop_id)).find_each do |build|
build.trace.archive!
end
end
end
end
end
require 'spec_helper'
describe Gitlab::BackgroundMigration::ArchiveLegacyTraces, :migration, schema: 20180529152628 do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:builds) { table(:ci_builds) }
let(:job_artifacts) { table(:ci_job_artifacts) }
before do
namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 123)
build = builds.create!(id: 1, project_id: 123, status: 'success')
@legacy_trace_dir = File.join(Settings.gitlab_ci.builds_path,
build.created_at.utc.strftime("%Y_%m"),
build.project_id.to_s)
FileUtils.mkdir_p(@legacy_trace_dir)
@legacy_trace_path = File.join(@legacy_trace_dir, "#{build.id}.log")
end
context 'when trace file exsits at the right place' do
before do
File.open(@legacy_trace_path, 'wb') { |stream| stream.write('aiueo') }
end
it 'correctly archive legacy traces' do
expect(job_artifacts.count).to eq(0)
expect(File.exist?(@legacy_trace_path)).to be_truthy
described_class.new.perform(1, 1)
expect(job_artifacts.count).to eq(1)
expect(File.exist?(@legacy_trace_path)).to be_falsy
expect(File.read(new_trace_path)).to eq('aiueo')
end
end
context 'when trace file does not exsits at the right place' do
it 'correctly archive legacy traces' do
expect(job_artifacts.count).to eq(0)
expect(File.exist?(@legacy_trace_path)).to be_falsy
described_class.new.perform(1, 1)
expect(job_artifacts.count).to eq(0)
end
end
def new_trace_path
job_artifact = job_artifacts.first
disk_hash = Digest::SHA2.hexdigest(job_artifact.project_id.to_s)
creation_date = job_artifact.created_at.utc.strftime('%Y_%m_%d')
File.join(Gitlab.config.artifacts.path, disk_hash[0..1], disk_hash[2..3], disk_hash,
creation_date, job_artifact.job_id.to_s, job_artifact.id.to_s, 'job.log')
end
end
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20180529152628_archive_legacy_traces')
describe ArchiveLegacyTraces, :migration do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:builds) { table(:ci_builds) }
let(:job_artifacts) { table(:ci_job_artifacts) }
before do
namespaces.create!(id: 123, name: 'gitlab1', path: 'gitlab1')
projects.create!(id: 123, name: 'gitlab1', path: 'gitlab1', namespace_id: 123)
build = builds.create!(id: 1)
@legacy_trace_path = File.join(
Settings.gitlab_ci.builds_path,
build.created_at.utc.strftime("%Y_%m"),
build.project_id.to_s,
"#{job.id}.log"
)
File.open(@legacy_trace_path, 'wb') { |stream| stream.write('aiueo') }
end
it 'correctly archive legacy traces' do
expect(job_artifacts.count).to eq(0)
expect(File.exist?(@legacy_trace_path)).to be_truthy
migrate!
expect(job_artifacts.count).to eq(1)
expect(File.exist?(@legacy_trace_path)).to be_falsy
expect(File.exist?(new_trace_path)).to be_truthy
end
def new_trace_path
job_artifact = job_artifacts.first
disk_hash = Digest::SHA2.hexdigest(job_artifact.project_id.to_s)
creation_date = job_artifact.created_at.utc.strftime('%Y_%m_%d')
File.join(disk_hash[0..1], disk_hash[2..3], disk_hash,
creation_date, job_artifact.job_id.to_s, job_artifact.id.to_s)
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment