debian-mirror-gitlab/app/services/projects/after_rename_service.rb

153 lines
4.2 KiB
Ruby
Raw Normal View History

2018-12-13 13:39:08 +05:30
# frozen_string_literal: true
module Projects
# Service class for performing operations that should take place after a
# project has been renamed.
#
# Example usage:
#
# project = Project.find(42)
#
# project.update(...)
#
# Projects::AfterRenameService.new(project).execute
class AfterRenameService
2021-11-18 22:05:49 +05:30
include BaseServiceUtility
2019-03-02 22:35:43 +05:30
# @return [String] The Project being renamed.
attr_reader :project
2018-12-13 13:39:08 +05:30
2019-03-02 22:35:43 +05:30
# @return [String] The path slug the project was using, before the rename took place.
attr_reader :path_before
2018-12-13 13:39:08 +05:30
2019-03-02 22:35:43 +05:30
# @return [String] The full path of the namespace + project, before the rename took place.
attr_reader :full_path_before
2018-12-13 13:39:08 +05:30
2019-03-02 22:35:43 +05:30
# @return [String] The full path of the namespace + project, after the rename took place.
attr_reader :full_path_after
2018-12-13 13:39:08 +05:30
2019-03-02 22:35:43 +05:30
RenameFailedError = Class.new(StandardError)
2018-12-13 13:39:08 +05:30
2019-03-02 22:35:43 +05:30
# @param [Project] project The Project being renamed.
# @param [String] path_before The path slug the project was using, before the rename took place.
def initialize(project, path_before:, full_path_before:)
@project = project
@path_before = path_before
@full_path_before = full_path_before
@full_path_after = project.full_path
2018-12-13 13:39:08 +05:30
end
def execute
first_ensure_no_registry_tags_are_present
expire_caches_before_rename
rename_or_migrate_repository!
send_move_instructions
execute_system_hooks
update_repository_configuration
rename_transferred_documents
log_completion
end
def first_ensure_no_registry_tags_are_present
return unless project.has_container_registry_tags?
2021-06-08 01:23:25 +05:30
raise RenameFailedError, "Project #{full_path_before} cannot be renamed because images are " \
2018-12-13 13:39:08 +05:30
"present in its container registry"
end
def expire_caches_before_rename
project.expire_caches_before_rename(full_path_before)
end
def rename_or_migrate_repository!
success =
if migrate_to_hashed_storage?
2019-03-02 22:35:43 +05:30
::Projects::HashedStorage::MigrationService
2018-12-13 13:39:08 +05:30
.new(project, full_path_before)
.execute
else
2019-03-02 22:35:43 +05:30
project.storage.rename_repo(old_full_path: full_path_before, new_full_path: full_path_after)
2018-12-13 13:39:08 +05:30
end
rename_failed! unless success
end
def send_move_instructions
return unless send_move_instructions?
project.send_move_instructions(full_path_before)
end
def execute_system_hooks
project.old_path_with_namespace = full_path_before
2021-11-18 22:05:49 +05:30
system_hook_service.execute_hooks_for(project, :rename)
2018-12-13 13:39:08 +05:30
end
def update_repository_configuration
project.reload_repository!
2021-10-27 15:23:28 +05:30
project.set_full_path
2019-02-15 15:39:39 +05:30
project.track_project_repository
2018-12-13 13:39:08 +05:30
end
def rename_transferred_documents
if rename_uploads?
Gitlab::UploadsTransfer
.new
.rename_project(path_before, project_path, namespace_full_path)
end
2020-11-24 15:15:51 +05:30
if project.pages_deployed?
# Block will be evaluated in the context of project so we need
# to bind to a local variable to capture it, as the instance
# variable and method aren't available on Project
path_before_local = @path_before
project.run_after_commit_or_now do
Gitlab::PagesTransfer
.new
.async
.rename_project(path_before_local, path, namespace.full_path)
end
end
2018-12-13 13:39:08 +05:30
end
def log_completion
2021-11-18 22:05:49 +05:30
log_info(
2018-12-13 13:39:08 +05:30
"Project #{project.id} has been renamed from " \
"#{full_path_before} to #{full_path_after}"
)
end
def migrate_to_hashed_storage?
Gitlab::CurrentSettings.hashed_storage_enabled? &&
2020-11-24 15:15:51 +05:30
project.storage_upgradable?
2018-12-13 13:39:08 +05:30
end
def send_move_instructions?
!project.import_started?
end
def rename_uploads?
!project.hashed_storage?(:attachments)
end
def project_path
project.path
end
def namespace_full_path
project.namespace.full_path
end
def rename_failed!
error = "Repository #{full_path_before} could not be renamed to #{full_path_after}"
2021-11-18 22:05:49 +05:30
log_error(error)
2018-12-13 13:39:08 +05:30
2021-06-08 01:23:25 +05:30
raise RenameFailedError, error
2018-12-13 13:39:08 +05:30
end
end
end
2019-12-04 20:38:33 +05:30
2021-06-08 01:23:25 +05:30
Projects::AfterRenameService.prepend_mod_with('Projects::AfterRenameService')