migrate_repository_service.rb 2.2 KB
Newer Older
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
module Projects
  module HashedStorage
    class MigrateRepositoryService < BaseService
      include Gitlab::ShellAdapter

      attr_reader :old_disk_path, :new_disk_path, :old_wiki_disk_path, :old_storage_version, :logger

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

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

        @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

        result = move_repository(@old_disk_path, @new_disk_path)

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

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

        project.repository_read_only = false
        project.save!

40 41 42 43
        if result && block_given?
          yield
        end

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 69 70 71 72
        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
    end
  end
end