PageRenderTime 53ms CodeModel.GetById 26ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/db/post_migrate/20170523083112_migrate_old_artifacts.rb

https://gitlab.com/visay/gitlab-ce
Ruby | 72 lines | 53 code | 17 blank | 2 comment | 1 complexity | 851b1902153d10a55befb75e5e3f820a MD5 | raw file
 1class MigrateOldArtifacts < ActiveRecord::Migration
 2  include Gitlab::Database::MigrationHelpers
 3
 4  DOWNTIME = false
 5
 6  disable_ddl_transaction!
 7
 8  # This uses special heuristic to find potential candidates for data migration
 9  # Read more about this here: https://gitlab.com/gitlab-org/gitlab-ce/issues/32036#note_30422345
10  
11  def up
12    builds_with_artifacts.find_each do |build|
13      build.migrate_artifacts!
14    end
15  end
16
17  def down
18  end
19
20  private
21
22  def builds_with_artifacts
23    Build.with_artifacts
24      .joins('JOIN projects ON projects.id = ci_builds.project_id')
25      .where('ci_builds.id < ?', min_id)
26      .where('projects.ci_id IS NOT NULL')
27      .select('id', 'created_at', 'project_id', 'projects.ci_id AS ci_id')
28  end
29
30  def min_id
31    Build.joins('JOIN projects ON projects.id = ci_builds.project_id')
32      .where('projects.ci_id IS NULL')
33      .pluck('coalesce(min(ci_builds.id), 0)')
34      .first
35  end
36
37  class Build < ActiveRecord::Base
38    self.table_name = 'ci_builds'
39
40    scope :with_artifacts, -> { where.not(artifacts_file: [nil, '']) }
41
42    def migrate_artifacts!
43      return unless File.exist?(source_artifacts_path)
44      return if File.exist?(target_artifacts_path)
45
46      ensure_target_path
47
48      FileUtils.move(source_artifacts_path, target_artifacts_path)
49    end
50
51    private
52
53    def source_artifacts_path
54      @source_artifacts_path ||= 
55        File.join(Gitlab.config.artifacts.path,
56          created_at.utc.strftime('%Y_%m'),
57          ci_id.to_s, id.to_s)
58    end
59
60    def target_artifacts_path
61      @target_artifacts_path ||= 
62        File.join(Gitlab.config.artifacts.path,
63          created_at.utc.strftime('%Y_%m'),
64          project_id.to_s, id.to_s)
65    end
66
67    def ensure_target_path
68      directory = File.dirname(target_artifacts_path)
69      FileUtils.mkdir_p(directory) unless Dir.exist?(directory)
70    end
71  end
72end