Read about our upcoming Code of Conduct on this issue

migrate_repository_service.rb 2.54 KB
Newer Older
1
2
# frozen_string_literal: true

3
4
5
6
7
module Projects
  module HashedStorage
    class MigrateRepositoryService < BaseService
      include Gitlab::ShellAdapter

8
      attr_reader :old_disk_path, :new_disk_path, :old_wiki_disk_path, :old_storage_version, :logger, :move_wiki
9

10
      def initialize(project, old_disk_path, logger: nil)
11
12
        @project = project
        @logger = logger || Rails.logger
13
14
15
        @old_disk_path = old_disk_path
        @old_wiki_disk_path = "#{old_disk_path}.wiki"
        @move_wiki = has_wiki?
16
17
18
19
20
21
22
23
24
      end

      def execute
        @old_storage_version = project.storage_version
        project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:repository]
        project.ensure_storage_path_exists

        @new_disk_path = project.disk_path

25
        result = move_repository(old_disk_path, new_disk_path)
26

27
28
        if move_wiki
          result &&= move_repository("#{old_wiki_disk_path}", "#{new_disk_path}.wiki")
29
30
        end

31
32
        if result
          project.write_repository_config
33
          project.track_project_repository
34
        else
35
          rollback_folder_move
36
          project.storage_version = nil
37
38
39
40
41
        end

        project.repository_read_only = false
        project.save!

42
43
44
45
        if result && block_given?
          yield
        end

46
47
48
49
50
        result
      end

      private

51
      # rubocop: disable CodeReuse/ActiveRecord
52
53
54
      def has_wiki?
        gitlab_shell.exists?(project.repository_storage, "#{old_wiki_disk_path}.git")
      end
55
      # rubocop: enable CodeReuse/ActiveRecord
56

57
      # rubocop: disable CodeReuse/ActiveRecord
58
      def move_repository(from_name, to_name)
59
60
        from_exists = gitlab_shell.exists?(project.repository_storage, "#{from_name}.git")
        to_exists = gitlab_shell.exists?(project.repository_storage, "#{to_name}.git")
61
62
63
64
65
66
67
68
69
70
71

        # 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

72
        gitlab_shell.mv_repository(project.repository_storage, from_name, to_name)
73
      end
74
      # rubocop: enable CodeReuse/ActiveRecord
75
76

      def rollback_folder_move
77
78
        move_repository(new_disk_path, old_disk_path)
        move_repository("#{new_disk_path}.wiki", old_wiki_disk_path)
79
80
81
82
      end
    end
  end
end