import_service.rb 2.38 KB
Newer Older
1
2
3
4
module Projects
  class ImportService < BaseService
    include Gitlab::ShellAdapter

5
    Error = Class.new(StandardError)
6
7

    def execute
8
      add_repository_to_project unless project.gitlab_project_import?
9
10
11
12

      import_data

      success
13
    rescue => e
14
      error("Error importing repository #{project.import_url} into #{project.full_path} - #{e.message}")
15
16
17
18
    end

    private

19
20
21
22
    def add_repository_to_project
      if unknown_url?
        # In this case, we only want to import issues, not a repository.
        create_repository
23
      elsif !project.repository_exists?
24
        import_repository
25
26
27
      end
    end

28
29
30
31
32
33
34
    def create_repository
      unless project.create_repository
        raise Error, 'The repository could not be created.'
      end
    end

    def import_repository
35
36
      raise Error, 'Blocked import URL.' if Gitlab::UrlBlocker.blocked_url?(project.import_url)

37
      begin
38
39
40
41
42
43
        if project.github_import? || project.gitea_import?
          fetch_repository
        else
          clone_repository
        end
      rescue Gitlab::Shell::Error => e
44
45
46
        # Expire cache to prevent scenarios such as:
        # 1. First import failed, but the repo was imported successfully, so +exists?+ returns true
        # 2. Retried import, repo is broken or not imported but +exists?+ still returns true
47
        project.repository.expire_content_cache if project.repository_exists?
48

49
        raise Error, e.message
50
51
52
      end
    end

53
54
55
    def clone_repository
      gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url)
    end
56

57
58
59
    def fetch_repository
      project.create_repository
      project.repository.add_remote(project.import_type, project.import_url)
60
      project.repository.set_remote_as_mirror(project.import_type)
61
      project.repository.fetch_remote(project.import_type, forced: true)
62
63
    end

64
65
66
    def import_data
      return unless has_importer?

67
      project.repository.expire_content_cache unless project.gitlab_project_import?
68

69
70
71
72
73
74
      unless importer.execute
        raise Error, 'The remote data could not be imported.'
      end
    end

    def has_importer?
Rémy Coutable's avatar
Rémy Coutable committed
75
      Gitlab::ImportSources.importer_names.include?(project.import_type)
76
77
78
    end

    def importer
Rémy Coutable's avatar
Rémy Coutable committed
79
      Gitlab::ImportSources.importer(project.import_type).new(project)
80
81
82
83
84
85
86
    end

    def unknown_url?
      project.import_url == Project::UNKNOWN_IMPORT_URL
    end
  end
end