summaryrefslogtreecommitdiff
path: root/app/services/projects/hashed_storage_migration_service.rb
blob: f5945f3b87f9aff9f630a7ce569e737156182597 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
module Projects
  class HashedStorageMigrationService < BaseService
    include Gitlab::ShellAdapter

    attr_reader :old_disk_path, :new_disk_path

    def initialize(project, logger = nil)
      @project = project
      @logger ||= Rails.logger
    end

    def execute
      return if project.hashed_storage?(:repository)

      @old_disk_path = project.disk_path
      has_wiki = project.wiki.repository_exists?

      project.storage_version = Storage::HashedProject::STORAGE_VERSION
      project.ensure_storage_path_exists

      @new_disk_path = project.disk_path

      result = move_repository(@old_disk_path, @new_disk_path)

      if has_wiki
        result &&= move_repository("#{@old_disk_path}.wiki", "#{@new_disk_path}.wiki")
      end

      unless result
        rollback_folder_move
        return
      end

      project.repository_read_only = false
      project.save!

      block_given? ? yield : result
    end

    private

    def move_repository(from_name, to_name)
      from_exists = gitlab_shell.exists?(project.repository_storage_path, "#{from_name}.git")
      to_exists = gitlab_shell.exists?(project.repository_storage_path, "#{to_name}.git")

      # If we don't find the repository on either original or target we should log that as it could be an issue if the
      # project was not originally empty.
      if !from_exists && !to_exists
        logger.warn "Can't find a repository on either source or target paths for #{project.full_path} (ID=#{project.id}) ..."
        return false
      elsif !from_exists
        # Repository have been moved already.
        return true
      end

      gitlab_shell.mv_repository(project.repository_storage_path, from_name, to_name)
    end

    def rollback_folder_move
      move_repository(@new_disk_path, @old_disk_path)
      move_repository("#{@new_disk_path}.wiki", "#{@old_disk_path}.wiki")
    end

    def logger
      @logger
    end
  end
end